# Copyright 2021 by Michiel de Hoon.  All rights reserved.
#
# This code is part of the Biopython distribution and governed by its
# license.  Please see the LICENSE file that should have been included
# as part of this package.
"""Tests for Bio.Align.tabular module."""
import os
import unittest
from tempfile import NamedTemporaryFile

from Bio import Align
from Bio.Align import substitution_matrices
from Bio import SeqIO
from Bio.Seq import Seq

try:
    import numpy as np
except ImportError:
    from Bio import MissingPythonDependencyError

    raise MissingPythonDependencyError(
        "Install numpy if you want to use Bio.Align.emboss."
    ) from None

substitution_matrix = substitution_matrices.load("BLOSUM62")


class TestFastaProtein(unittest.TestCase):
    query = Seq(
        "MPMILGYWNVRGLTHPIRMLLEYTDSSYDEKRYTMGDAPDFDRSQWLNEKFKLGLDFPNLPYLIDGSHKITQSNAILRYLARKHHLDGETEEERIRADIVENQVMDTRMQLIMLCYNPDFEKQKPEFLKTIPEKMKLYSEFLGKRPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKKISAYMKSSRYIATPIFSKMAHWSNK"
    )

    filename = os.path.join("Fasta", "protein_lib.fa")
    records = SeqIO.parse(filename, "fasta")
    targets = {record.id: record.seq.upper() for record in records}

    def test_m8CB(self):
        # Alignment file obtained by running
        # fasta36 -q -m 8CB seq/mgstm1.aa seq/prot_test.lseg
        # in the fasta36 source distribution
        path = "Fasta/protein_m8CB.txt"
        alignments = Align.parse(path, "tabular")
        self.check_m8CB(alignments)
        alignments = iter(alignments)
        self.check_m8CB(alignments)
        with Align.parse(path, "tabular") as alignments:
            self.check_m8CB(alignments)
        with self.assertRaises(AttributeError):
            alignments._stream
        with Align.parse(path, "tabular") as alignments:
            pass
        with self.assertRaises(AttributeError):
            alignments._stream
        with open(path) as stream:
            data = stream.read()
        stream = NamedTemporaryFile("w+t")
        stream.write(data)
        stream.seek(0)
        alignments = Align.parse(stream, "tabular")
        self.check_m8CB(alignments)

    def check_m8CB(self, alignments):
        self.assertEqual(
            alignments.metadata["Command line"],
            "fasta36 -q -m 8CB seq/mgstm1.aa seq/prot_test.lseg",
        )
        self.assertEqual(alignments.metadata["Program"], "FASTA")
        self.assertEqual(alignments.metadata["Version"], "36.3.8h May, 2020")
        self.assertEqual(alignments.metadata["Database"], "seq/prot_test.lseg")
        # sp|P10649|GSTM1_MOUSE   sp|P09488|GSTM1_HUMAN
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 77.98)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 218)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 218)
        self.assertEqual(alignment.shape, (2, 218 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P09488|GSTM1_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 48)
        self.assertAlmostEqual(alignment.annotations["evalue"], 6.1e-78, places=79)
        self.assertAlmostEqual(alignment.annotations["bit score"], 275.6)
        self.assertEqual(
            str(alignment),
            """\
sp|P09488         0 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649         0 ????????????????????????????????????????????????????????????

sp|P09488        60 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649        60 ????????????????????????????????????????????????????????????

sp|P09488       120 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649       120 ????????????????????????????????????????????????????????????

sp|P09488       180 ?????????????????????????????????????? 218
                180 |||||||||||||||||||||||||||||||||||||| 218
sp|P10649       180 ?????????????????????????????????????? 218
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[0, 218], [0, 218]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 218)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "MPMILGYWDIRGLAHAIRLLLEYTDSSYEEKKYTMGDAPDYDRSQWLNEKFKLGLDFPNLPYLIDGAHKITQSNAILCYIARKHNLCGETEEEKIRVDILENQTMDNHMQLGMICYNPEFEKLKPKYLEELPEKLKLYSEFLGKRPWFAGNKITFVDFLVYDVLDLHRIFEPKCLDAFPNLKDFISRFEGLEKISAYMKSSRFLPRPVFSKMAVWGNK",
        )
        self.assertEqual(
            alignment[1],
            "MPMILGYWNVRGLTHPIRMLLEYTDSSYDEKRYTMGDAPDFDRSQWLNEKFKLGLDFPNLPYLIDGSHKITQSNAILRYLARKHHLDGETEEERIRADIVENQVMDTRMQLIMLCYNPDFEKQKPEFLKTIPEKMKLYSEFLGKRPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKKISAYMKSSRYIATPIFSKMAHWSNK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P00502|GSTA1_RAT
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['M', 'P', 'M', 'I', 'L', 'G', 'Y', 'W', 'D', 'I', 'R', 'G', 'L',
           'A', 'H', 'A', 'I', 'R', 'L', 'L', 'L', 'E', 'Y', 'T', 'D', 'S',
           'S', 'Y', 'E', 'E', 'K', 'K', 'Y', 'T', 'M', 'G', 'D', 'A', 'P',
           'D', 'Y', 'D', 'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K',
           'L', 'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D',
           'G', 'A', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'C',
           'Y', 'I', 'A', 'R', 'K', 'H', 'N', 'L', 'C', 'G', 'E', 'T', 'E',
           'E', 'E', 'K', 'I', 'R', 'V', 'D', 'I', 'L', 'E', 'N', 'Q', 'T',
           'M', 'D', 'N', 'H', 'M', 'Q', 'L', 'G', 'M', 'I', 'C', 'Y', 'N',
           'P', 'E', 'F', 'E', 'K', 'L', 'K', 'P', 'K', 'Y', 'L', 'E', 'E',
           'L', 'P', 'E', 'K', 'L', 'K', 'L', 'Y', 'S', 'E', 'F', 'L', 'G',
           'K', 'R', 'P', 'W', 'F', 'A', 'G', 'N', 'K', 'I', 'T', 'F', 'V',
           'D', 'F', 'L', 'V', 'Y', 'D', 'V', 'L', 'D', 'L', 'H', 'R', 'I',
           'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A', 'F', 'P', 'N', 'L', 'K',
           'D', 'F', 'I', 'S', 'R', 'F', 'E', 'G', 'L', 'E', 'K', 'I', 'S',
           'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'F', 'L', 'P', 'R', 'P', 'V',
           'F', 'S', 'K', 'M', 'A', 'V', 'W', 'G', 'N', 'K'],
          ['M', 'P', 'M', 'I', 'L', 'G', 'Y', 'W', 'N', 'V', 'R', 'G', 'L',
           'T', 'H', 'P', 'I', 'R', 'M', 'L', 'L', 'E', 'Y', 'T', 'D', 'S',
           'S', 'Y', 'D', 'E', 'K', 'R', 'Y', 'T', 'M', 'G', 'D', 'A', 'P',
           'D', 'F', 'D', 'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K',
           'L', 'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D',
           'G', 'S', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'R',
           'Y', 'L', 'A', 'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E',
           'E', 'E', 'R', 'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V',
           'M', 'D', 'T', 'R', 'M', 'Q', 'L', 'I', 'M', 'L', 'C', 'Y', 'N',
           'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P', 'E', 'F', 'L', 'K', 'T',
           'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E', 'F', 'L', 'G',
           'K', 'R', 'P', 'W', 'F', 'A', 'G', 'D', 'K', 'V', 'T', 'Y', 'V',
           'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L', 'D', 'Q', 'Y', 'R', 'M',
           'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A', 'F', 'P', 'N', 'L', 'R',
           'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G', 'L', 'K', 'K', 'I', 'S',
           'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'Y', 'I', 'A', 'T', 'P', 'I',
           'F', 'S', 'K', 'M', 'A', 'H', 'W', 'S', 'N', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 967.0; 218 aligned letters; 170 identities; 48 mismatches; 201 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 967.0,
    aligned = 218:
        identities = 170,
        positives = 201,
        mismatches = 48.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 218)
        self.assertEqual(counts.identities, 170)
        self.assertEqual(counts.mismatches, 48)
        self.assertEqual(counts.positives, 201)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 29.76)
        self.assertEqual(alignment.annotations["gap opens"], 18)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 205)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 205)
        self.assertEqual(alignment.shape, (2, 205 + 18))
        self.assertEqual(alignment.sequences[0].id, "sp|P00502|GSTA1_RAT")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 144)
        self.assertAlmostEqual(alignment.annotations["evalue"], 3.1e-13, places=14)
        self.assertAlmostEqual(alignment.annotations["bit score"], 60.7)
        self.assertEqual(
            str(alignment),
            """\
sp|P00502         5 ????????????????????????????---------???????????????????????
                  0 ||||||||||||||||||||||||||||---------|||||||||||||--||||||||
sp|P10649         3 ??????????????????????????????????????????????????--????????

sp|P00502        56 ??????-?????????????????????????????????????????????????????
                 60 ||-|||-|||||||||||||||||||||||||||||||||||||||-|||||||||||||
sp|P10649        61 ??-???????????????????????????????????????????-?????????????

sp|P00502       115 ????????????????????????????????????????????????????????????
                120 ||||||||||--|||||||||||||||--|||||||||||||||||||||||||||||||
sp|P10649       119 ??????????--???????????????--???????????????????????????????

sp|P00502       175 ??????????????????????????????????????????? 218
                180 ||||||||||||||||||||||||||||||||||||||||||| 223
sp|P10649       175 ??????????????????????????????????????????? 218
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 5,  33,  33,  46,  48,  58,  59,  62,
                           62, 101, 102, 125, 127, 142, 144, 218],
                          [ 3,  31,  40,  53,  53,  63,  63,  66,
                           67, 106, 106, 129, 129, 144, 144, 218]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 218)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "VLHYFNARGRMECIRWLLAAAGVEFDEK---------FIQSPEDLEKLKKDGNLMFDQVPMVEIDG-MKLAQTRAILNYIATKYDLYGKDMKERALIDMYTEGILDLTEMIMQLVICPPDQKEAKTALAKDRTKNRYLPAFEKVLKSHGQDYLVGNRLTRVDIHLLELLLYVEEFDASLLTSFPLLKAFKSRISSLPNVKKFLQPGSQRKLPVDAKQIEEARK",
        )
        self.assertEqual(
            alignment[1],
            "ILGYWNVRGLTHPIRMLLEYTDSSYDEKRYTMGDAPDFDRSQWLNEKFKL--GLDFPNLPYL-IDGSHKITQSNAILRYLARKHHLDGETEEERIRADIVENQVMD-TRMQLIMLCYNPDFEKQKPEFLK--TIPEKMKLYSEFLGK--RPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKKISAYMKSSRYIATPIFSKMAHWSNK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P69905|HBA_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['V', 'L', 'H', 'Y', 'F', 'N', 'A', 'R', 'G', 'R', 'M', 'E', 'C',
           'I', 'R', 'W', 'L', 'L', 'A', 'A', 'A', 'G', 'V', 'E', 'F', 'D',
           'E', 'K', '-', '-', '-', '-', '-', '-', '-', '-', '-', 'F', 'I',
           'Q', 'S', 'P', 'E', 'D', 'L', 'E', 'K', 'L', 'K', 'K', 'D', 'G',
           'N', 'L', 'M', 'F', 'D', 'Q', 'V', 'P', 'M', 'V', 'E', 'I', 'D',
           'G', '-', 'M', 'K', 'L', 'A', 'Q', 'T', 'R', 'A', 'I', 'L', 'N',
           'Y', 'I', 'A', 'T', 'K', 'Y', 'D', 'L', 'Y', 'G', 'K', 'D', 'M',
           'K', 'E', 'R', 'A', 'L', 'I', 'D', 'M', 'Y', 'T', 'E', 'G', 'I',
           'L', 'D', 'L', 'T', 'E', 'M', 'I', 'M', 'Q', 'L', 'V', 'I', 'C',
           'P', 'P', 'D', 'Q', 'K', 'E', 'A', 'K', 'T', 'A', 'L', 'A', 'K',
           'D', 'R', 'T', 'K', 'N', 'R', 'Y', 'L', 'P', 'A', 'F', 'E', 'K',
           'V', 'L', 'K', 'S', 'H', 'G', 'Q', 'D', 'Y', 'L', 'V', 'G', 'N',
           'R', 'L', 'T', 'R', 'V', 'D', 'I', 'H', 'L', 'L', 'E', 'L', 'L',
           'L', 'Y', 'V', 'E', 'E', 'F', 'D', 'A', 'S', 'L', 'L', 'T', 'S',
           'F', 'P', 'L', 'L', 'K', 'A', 'F', 'K', 'S', 'R', 'I', 'S', 'S',
           'L', 'P', 'N', 'V', 'K', 'K', 'F', 'L', 'Q', 'P', 'G', 'S', 'Q',
           'R', 'K', 'L', 'P', 'V', 'D', 'A', 'K', 'Q', 'I', 'E', 'E', 'A',
           'R', 'K'],
          ['I', 'L', 'G', 'Y', 'W', 'N', 'V', 'R', 'G', 'L', 'T', 'H', 'P',
           'I', 'R', 'M', 'L', 'L', 'E', 'Y', 'T', 'D', 'S', 'S', 'Y', 'D',
           'E', 'K', 'R', 'Y', 'T', 'M', 'G', 'D', 'A', 'P', 'D', 'F', 'D',
           'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K', 'L', '-', '-',
           'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', '-', 'I', 'D',
           'G', 'S', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'R',
           'Y', 'L', 'A', 'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E',
           'E', 'E', 'R', 'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V',
           'M', 'D', '-', 'T', 'R', 'M', 'Q', 'L', 'I', 'M', 'L', 'C', 'Y',
           'N', 'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P', 'E', 'F', 'L', 'K',
           '-', '-', 'T', 'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E',
           'F', 'L', 'G', 'K', '-', '-', 'R', 'P', 'W', 'F', 'A', 'G', 'D',
           'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L',
           'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A',
           'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G',
           'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'Y',
           'I', 'A', 'T', 'P', 'I', 'F', 'S', 'K', 'M', 'A', 'H', 'W', 'S',
           'N', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 257.0; 205 aligned letters; 61 identities; 144 mismatches; 102 positives; 18 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 257.0,
    aligned = 205:
        identities = 61,
        positives = 102,
        mismatches = 144.
    gaps = 18:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 18:
            internal_insertions = 10:
                open_internal_insertions = 2,
                extend_internal_insertions = 8;
            internal_deletions = 8:
                open_internal_deletions = 5,
                extend_internal_deletions = 3;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 10)
        self.assertEqual(counts.internal_deletions, 8)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 18)
        self.assertEqual(counts.insertions, 10)
        self.assertEqual(counts.deletions, 8)
        self.assertEqual(counts.gaps, 18)
        self.assertEqual(counts.aligned, 205)
        self.assertEqual(counts.identities, 61)
        self.assertEqual(counts.mismatches, 144)
        self.assertEqual(counts.positives, 102)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 27.03)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 37)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 37)
        self.assertEqual(alignment.shape, (2, 37 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P69905|HBA_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 27)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.19)
        self.assertAlmostEqual(alignment.annotations["bit score"], 20.9)
        self.assertEqual(
            str(alignment),
            """\
sp|P69905        35 ?????????????-?????????????????????????  73
                  0 |||||||||||||-||||||||||-||||||||||||||  39
sp|P10649       176 ????????????????????????-?????????????? 214
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 35,  48,  48,  58,  59,  73],
                          [176, 189, 190, 200, 200, 214]]),
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 73)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "SFPTTKTYFPHFD-LSHGSAQVKGHGKKVADALTNAVAH")
        self.assertEqual(alignment[1], "AFPNLRDFLARFEGLKKISAYMKS-SRYIATPIFSKMAH")
        # sp|P10649|GSTM1_MOUSE   sp|P00517|KAPCA_BOVIN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['S', 'F', 'P', 'T', 'T', 'K', 'T', 'Y', 'F', 'P', 'H', 'F', 'D',
           '-', 'L', 'S', 'H', 'G', 'S', 'A', 'Q', 'V', 'K', 'G', 'H', 'G',
           'K', 'K', 'V', 'A', 'D', 'A', 'L', 'T', 'N', 'A', 'V', 'A', 'H'],
          ['A', 'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E',
           'G', 'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K', 'S', '-', 'S',
           'R', 'Y', 'I', 'A', 'T', 'P', 'I', 'F', 'S', 'K', 'M', 'A', 'H']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 54.0; 37 aligned letters; 10 identities; 27 mismatches; 20 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 54.0,
    aligned = 37:
        identities = 10,
        positives = 20,
        mismatches = 27.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 37)
        self.assertEqual(counts.identities, 10)
        self.assertEqual(counts.mismatches, 27)
        self.assertEqual(counts.positives, 20)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 24.29)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 70)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 70)
        self.assertEqual(alignment.shape, (2, 70 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P00517|KAPCA_BOVIN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 53)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.4)
        self.assertAlmostEqual(alignment.annotations["bit score"], 19.2)
        self.assertEqual(
            str(alignment),
            """\
sp|P00517       228 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||--||||||||||||
sp|P10649       136 ??????????????????????????????????????????????--????????????

sp|P00517       288 ???????????? 300
                 60 ||||||||||||  72
sp|P10649       194 ???????????? 206
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[228, 274, 276, 300],
                          [136, 182, 182, 206]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 300)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "IYEMAAGYPPFFADQPIQIYEKIVSGKVRFPSHFSSDLKDLLRNLLQVDLTKRFGNLKNGVNDIKNHKWFAT",
        )
        self.assertEqual(
            alignment[1],
            "LYSEFLGKRPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLR--DFLARFEGLKKISAYMKSSRYIAT",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P14960|RBS_GUITH
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['I', 'Y', 'E', 'M', 'A', 'A', 'G', 'Y', 'P', 'P', 'F', 'F', 'A',
           'D', 'Q', 'P', 'I', 'Q', 'I', 'Y', 'E', 'K', 'I', 'V', 'S', 'G',
           'K', 'V', 'R', 'F', 'P', 'S', 'H', 'F', 'S', 'S', 'D', 'L', 'K',
           'D', 'L', 'L', 'R', 'N', 'L', 'L', 'Q', 'V', 'D', 'L', 'T', 'K',
           'R', 'F', 'G', 'N', 'L', 'K', 'N', 'G', 'V', 'N', 'D', 'I', 'K',
           'N', 'H', 'K', 'W', 'F', 'A', 'T'],
          ['L', 'Y', 'S', 'E', 'F', 'L', 'G', 'K', 'R', 'P', 'W', 'F', 'A',
           'G', 'D', 'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D',
           'I', 'L', 'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L',
           'D', 'A', 'F', 'P', 'N', 'L', 'R', '-', '-', 'D', 'F', 'L', 'A',
           'R', 'F', 'E', 'G', 'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K',
           'S', 'S', 'R', 'Y', 'I', 'A', 'T']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 49.0; 70 aligned letters; 17 identities; 53 mismatches; 27 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 49.0,
    aligned = 70:
        identities = 17,
        positives = 27,
        mismatches = 53.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 2:
                open_internal_deletions = 1,
                extend_internal_deletions = 1;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 2)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 2)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 70)
        self.assertEqual(counts.identities, 17)
        self.assertEqual(counts.mismatches, 53)
        self.assertEqual(counts.positives, 27)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 57.14)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 7)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 7)
        self.assertEqual(alignment.shape, (2, 7 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P14960|RBS_GUITH")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 3)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.6)
        self.assertAlmostEqual(alignment.annotations["bit score"], 17.7)
        self.assertEqual(
            str(alignment),
            """\
sp|P14960        46 ??????? 53
                  0 |||||||  7
sp|P10649         6 ??????? 13
""",
        )
        self.assertTrue(
            np.array_equal(alignment.coordinates, np.array([[46, 53], [6, 13]]))
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 53)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "YWDLWGL")
        self.assertEqual(alignment[1], "YWNVRGL")
        # sp|P10649|GSTM1_MOUSE   sp|P01593|KV101_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['Y', 'W', 'D', 'L', 'W', 'G', 'L'],
          ['Y', 'W', 'N', 'V', 'R', 'G', 'L']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 27.0; 7 aligned letters; 4 identities; 3 mismatches; 6 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 27.0,
    aligned = 7:
        identities = 4,
        positives = 6,
        mismatches = 3.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 7)
        self.assertEqual(counts.identities, 4)
        self.assertEqual(counts.mismatches, 3)
        self.assertEqual(counts.positives, 6)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 45.00)
        self.assertEqual(alignment.annotations["gap opens"], 10)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 40)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 40)
        self.assertEqual(alignment.shape, (2, 40 + 10))
        self.assertEqual(alignment.sequences[0].id, "sp|P01593|KV101_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 22)
        self.assertAlmostEqual(alignment.annotations["evalue"], 2.5)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.6)
        self.assertEqual(
            str(alignment),
            """\
sp|P01593        15 ????????????????????????????????????-?????????????  64
                  0 ||||||||||||||---||||||||---||||--||-|||||||-|||||  50
sp|P10649       149 ??????????????---????????---????--??????????-????? 190
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 15,  29,  32,  40,  43,  47,
                            49,  51,  51,  58,  59,  64],
                          [149, 163, 163, 171, 171, 175,
                           175, 177, 178, 185, 185, 190]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 64)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0], "GDRVTITCQASQDINHYLNWYQQGPKKAPKILIYDA-SNLETGVPSRFSG"
        )
        self.assertEqual(
            alignment[1], "GDKVTYVDFLAYDI---LDQYRMFE---PKCL--DAFPNLRDFL-ARFEG"
        )
        # sp|P10649|GSTM1_MOUSE   sp|P99998|CYC_PANTR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'D', 'R', 'V', 'T', 'I', 'T', 'C', 'Q', 'A', 'S', 'Q', 'D',
           'I', 'N', 'H', 'Y', 'L', 'N', 'W', 'Y', 'Q', 'Q', 'G', 'P', 'K',
           'K', 'A', 'P', 'K', 'I', 'L', 'I', 'Y', 'D', 'A', '-', 'S', 'N',
           'L', 'E', 'T', 'G', 'V', 'P', 'S', 'R', 'F', 'S', 'G'],
          ['G', 'D', 'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D',
           'I', '-', '-', '-', 'L', 'D', 'Q', 'Y', 'R', 'M', 'F', 'E', '-',
           '-', '-', 'P', 'K', 'C', 'L', '-', '-', 'D', 'A', 'F', 'P', 'N',
           'L', 'R', 'D', 'F', 'L', '-', 'A', 'R', 'F', 'E', 'G']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 81.0; 40 aligned letters; 18 identities; 22 mismatches; 24 positives; 10 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 81.0,
    aligned = 40:
        identities = 18,
        positives = 24,
        mismatches = 22.
    gaps = 10:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 10:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 9:
                open_internal_deletions = 4,
                extend_internal_deletions = 5;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 9)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 10)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 9)
        self.assertEqual(counts.gaps, 10)
        self.assertEqual(counts.aligned, 40)
        self.assertEqual(counts.identities, 18)
        self.assertEqual(counts.mismatches, 22)
        self.assertEqual(counts.positives, 24)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 31.03)
        self.assertEqual(alignment.annotations["gap opens"], 10)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 58)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 58)
        self.assertEqual(alignment.shape, (2, 58 + 10))
        self.assertEqual(alignment.sequences[0].id, "sp|P99998|CYC_PANTR")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 40)
        self.assertAlmostEqual(alignment.annotations["evalue"], 2.7)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.4)
        self.assertEqual(
            str(alignment),
            """\
sp|P99998        27 ???????????????????????????????-??????????-?????--?????????-
                  0 ||||||||||||||||||||---||||||||-||||||||||-|||||--|||||||||-
sp|P10649       128 ????????????????????---?????????????????????????????????????

sp|P99998        82 --??????  88
                 60 --||||||  68
sp|P10649       185 ???????? 193
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 27,  47,  50,  58,  58,  68,
                            68,  73,  73,  82,  82,  88],
                          [128, 148, 148, 156, 157, 167,
                           168, 173, 175, 184, 187, 193]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 88)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "KTGPNLHGLFGRKTGQAPGYSYTAANKNKGI-IWGEDTLMEY-LENPK--KYIPGTKMI---FVGIKK",
        )
        self.assertEqual(
            alignment[1],
            "KTIPEKMKLYSEFLGKRPWF---AGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P02585|TNNC2_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['K', 'T', 'G', 'P', 'N', 'L', 'H', 'G', 'L', 'F', 'G', 'R', 'K',
           'T', 'G', 'Q', 'A', 'P', 'G', 'Y', 'S', 'Y', 'T', 'A', 'A', 'N',
           'K', 'N', 'K', 'G', 'I', '-', 'I', 'W', 'G', 'E', 'D', 'T', 'L',
           'M', 'E', 'Y', '-', 'L', 'E', 'N', 'P', 'K', '-', '-', 'K', 'Y',
           'I', 'P', 'G', 'T', 'K', 'M', 'I', '-', '-', '-', 'F', 'V', 'G',
           'I', 'K', 'K'],
          ['K', 'T', 'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E', 'F',
           'L', 'G', 'K', 'R', 'P', 'W', 'F', '-', '-', '-', 'A', 'G', 'D',
           'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L',
           'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A',
           'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G',
           'L', 'K', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 76.0; 58 aligned letters; 18 identities; 40 mismatches; 27 positives; 10 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 58:
        identities = 18,
        positives = 27,
        mismatches = 40.
    gaps = 10:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 10:
            internal_insertions = 7:
                open_internal_insertions = 4,
                extend_internal_insertions = 3;
            internal_deletions = 3:
                open_internal_deletions = 1,
                extend_internal_deletions = 2;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 7)
        self.assertEqual(counts.internal_deletions, 3)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 10)
        self.assertEqual(counts.insertions, 7)
        self.assertEqual(counts.deletions, 3)
        self.assertEqual(counts.gaps, 10)
        self.assertEqual(counts.aligned, 58)
        self.assertEqual(counts.identities, 18)
        self.assertEqual(counts.mismatches, 40)
        self.assertEqual(counts.positives, 27)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 31.11)
        self.assertEqual(alignment.annotations["gap opens"], 9)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 45)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 45)
        self.assertEqual(alignment.shape, (2, 45 + 9))
        self.assertEqual(alignment.sequences[0].id, "sp|P02585|TNNC2_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 31)
        self.assertAlmostEqual(alignment.annotations["evalue"], 3.9)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.4)
        self.assertEqual(
            str(alignment),
            """\
sp|P02585        12 ??????????????----???????????????????????????????????? 62
                  0 ||||||||||||||----||||||||||--|||||||||||---|||||||||| 54
sp|P10649        43 ????????????????????????????--???????????---?????????? 92
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array(
                    [[12, 26, 26, 36, 38, 49, 52, 62],
                     [43, 57, 61, 71, 71, 82, 82, 92]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 62)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0], "SEEMIAEFKAAFDM----FDADGGGDISVKELGTVMRMLGQTPTKEELDAIIEE"
        )
        self.assertEqual(
            alignment[1], "SQWLNEKFKLGLDFPNLPYLIDGSHKIT--QSNAILRYLAR---KHHLDGETEE"
        )
        # sp|P10649|GSTM1_MOUSE   sp|P60615|NXL1A_BUNMU
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['S', 'E', 'E', 'M', 'I', 'A', 'E', 'F', 'K', 'A', 'A', 'F', 'D',
           'M', '-', '-', '-', '-', 'F', 'D', 'A', 'D', 'G', 'G', 'G', 'D',
           'I', 'S', 'V', 'K', 'E', 'L', 'G', 'T', 'V', 'M', 'R', 'M', 'L',
           'G', 'Q', 'T', 'P', 'T', 'K', 'E', 'E', 'L', 'D', 'A', 'I', 'I',
           'E', 'E'],
          ['S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K', 'L', 'G', 'L', 'D',
           'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D', 'G', 'S', 'H', 'K',
           'I', 'T', '-', '-', 'Q', 'S', 'N', 'A', 'I', 'L', 'R', 'Y', 'L',
           'A', 'R', '-', '-', '-', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T',
           'E', 'E']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 65.0; 45 aligned letters; 14 identities; 31 mismatches; 23 positives; 9 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 65.0,
    aligned = 45:
        identities = 14,
        positives = 23,
        mismatches = 31.
    gaps = 9:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 9:
            internal_insertions = 4:
                open_internal_insertions = 1,
                extend_internal_insertions = 3;
            internal_deletions = 5:
                open_internal_deletions = 2,
                extend_internal_deletions = 3;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 4)
        self.assertEqual(counts.internal_deletions, 5)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 9)
        self.assertEqual(counts.insertions, 4)
        self.assertEqual(counts.deletions, 5)
        self.assertEqual(counts.gaps, 9)
        self.assertEqual(counts.aligned, 45)
        self.assertEqual(counts.identities, 14)
        self.assertEqual(counts.mismatches, 31)
        self.assertEqual(counts.positives, 23)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 66.67)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 9)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 9)
        self.assertEqual(alignment.shape, (2, 9 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P60615|NXL1A_BUNMU")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 3)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.2)
        self.assertAlmostEqual(alignment.annotations["bit score"], 15.6)
        self.assertEqual(
            str(alignment),
            """\
sp|P60615        85 ?-???-?????  94
                  0 |-|||-|||||  11
sp|P10649       114 ??????????? 125
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 85,  86,  86,  89,  89,  94],
                          [114, 115, 116, 119, 120, 125]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 94)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "C-NPH-PKQRP")
        self.assertEqual(alignment[1], "CYNPDFEKQKP")
        # sp|P10649|GSTM1_MOUSE   sp|P00193|FER_PEPAS
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', '-', 'N', 'P', 'H', '-', 'P', 'K', 'Q', 'R', 'P'],
          ['C', 'Y', 'N', 'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 39.0; 9 aligned letters; 6 identities; 3 mismatches; 7 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 39.0,
    aligned = 9:
        identities = 6,
        positives = 7,
        mismatches = 3.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 2:
                open_internal_insertions = 2,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 2)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 2)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 9)
        self.assertEqual(counts.identities, 6)
        self.assertEqual(counts.mismatches, 3)
        self.assertEqual(counts.positives, 7)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 50.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 4)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 4)
        self.assertEqual(alignment.shape, (2, 4 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P00193|FER_PEPAS")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.2)
        self.assertAlmostEqual(alignment.annotations["bit score"], 14.7)
        self.assertEqual(
            str(alignment),
            """\
sp|P00193        14 ????  18
                  0 ||||   4
sp|P10649       170 ???? 174
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[14, 18], [170, 174]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 18)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "KPEC")
        self.assertEqual(alignment[1], "EPKC")
        # sp|P10649|GSTM1_MOUSE   sp|P03435|HEMA_I75A3
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['K', 'P', 'E', 'C'],
          ['E', 'P', 'K', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 18.0; 4 aligned letters; 2 identities; 2 mismatches; 4 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 18.0,
    aligned = 4:
        identities = 2,
        positives = 4,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 4)
        self.assertEqual(counts.identities, 2)
        self.assertEqual(counts.mismatches, 2)
        self.assertEqual(counts.positives, 4)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 28.95)
        self.assertEqual(alignment.annotations["gap opens"], 1)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 38)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 38)
        self.assertEqual(alignment.shape, (2, 38 + 1))
        self.assertEqual(alignment.sequences[0].id, "sp|P03435|HEMA_I75A3")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 27)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.7)
        self.assertAlmostEqual(alignment.annotations["bit score"], 17.9)
        self.assertEqual(
            str(alignment),
            """\
sp|P03435       398 ??????????????????????????????????????? 437
                  0 ||||||||||-||||||||||||||||||||||||||||  39
sp|P10649        73 ??????????-???????????????????????????? 111
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[398, 408, 409, 437], [73, 83, 83, 111]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 437)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "NRVIEKTNEKFHQIEKEFSEVEGRIQDLEKYVEDTKIDL")
        self.assertEqual(alignment[1], "NAILRYLARK-HHLDGETEEERIRADIVENQVMDTRMQL")
        # sp|P10649|GSTM1_MOUSE   sp|P01834|IGKC_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['N', 'R', 'V', 'I', 'E', 'K', 'T', 'N', 'E', 'K', 'F', 'H', 'Q',
           'I', 'E', 'K', 'E', 'F', 'S', 'E', 'V', 'E', 'G', 'R', 'I', 'Q',
           'D', 'L', 'E', 'K', 'Y', 'V', 'E', 'D', 'T', 'K', 'I', 'D', 'L'],
          ['N', 'A', 'I', 'L', 'R', 'Y', 'L', 'A', 'R', 'K', '-', 'H', 'H',
           'L', 'D', 'G', 'E', 'T', 'E', 'E', 'E', 'R', 'I', 'R', 'A', 'D',
           'I', 'V', 'E', 'N', 'Q', 'V', 'M', 'D', 'T', 'R', 'M', 'Q', 'L']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 48.0; 38 aligned letters; 11 identities; 27 mismatches; 18 positives; 1 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 48.0,
    aligned = 38:
        identities = 11,
        positives = 18,
        mismatches = 27.
    gaps = 1:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 1:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 1)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 1)
        self.assertEqual(counts.aligned, 38)
        self.assertEqual(counts.identities, 11)
        self.assertEqual(counts.mismatches, 27)
        self.assertEqual(counts.positives, 18)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 19.40)
        self.assertEqual(alignment.annotations["gap opens"], 4)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 67)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 67)
        self.assertEqual(alignment.shape, (2, 67 + 4))
        self.assertEqual(alignment.sequences[0].id, "sp|P01834|IGKC_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 54)
        self.assertAlmostEqual(alignment.annotations["evalue"], 6.3)
        self.assertAlmostEqual(alignment.annotations["bit score"], 14.9)
        self.assertEqual(
            str(alignment),
            """\
sp|P01834        11 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||--||||||||||||||||||||||||||||||||||||||||--||
sp|P10649        57 ??????????????--????????????????????????????????????????--??

sp|P01834        71 ???????????  82
                 60 |||||||||||  71
sp|P10649       113 ??????????? 124
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[11, 25, 27,  67,  69,  82],
                          [57, 71, 71, 111, 111, 124]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 82)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "PSDEQLKSGTASVVCLLNNFYPREAKVQWKVDNALQSGNSQESVTEQDSKDSTYSLSSTLTLSKADYEKHK",
        )
        self.assertEqual(
            alignment[1],
            "PNLPYLIDGSHKIT--QSNAILRYLARKHHLDGETEEERIRADIVENQVMDTRMQL--IMLCYNPDFEKQK",
        )
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['P', 'S', 'D', 'E', 'Q', 'L', 'K', 'S', 'G', 'T', 'A', 'S', 'V',
           'V', 'C', 'L', 'L', 'N', 'N', 'F', 'Y', 'P', 'R', 'E', 'A', 'K',
           'V', 'Q', 'W', 'K', 'V', 'D', 'N', 'A', 'L', 'Q', 'S', 'G', 'N',
           'S', 'Q', 'E', 'S', 'V', 'T', 'E', 'Q', 'D', 'S', 'K', 'D', 'S',
           'T', 'Y', 'S', 'L', 'S', 'S', 'T', 'L', 'T', 'L', 'S', 'K', 'A',
           'D', 'Y', 'E', 'K', 'H', 'K'],
          ['P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D', 'G', 'S', 'H', 'K', 'I',
           'T', '-', '-', 'Q', 'S', 'N', 'A', 'I', 'L', 'R', 'Y', 'L', 'A',
           'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E', 'E', 'E', 'R',
           'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V', 'M', 'D', 'T',
           'R', 'M', 'Q', 'L', '-', '-', 'I', 'M', 'L', 'C', 'Y', 'N', 'P',
           'D', 'F', 'E', 'K', 'Q', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 43.0; 67 aligned letters; 13 identities; 54 mismatches; 25 positives; 4 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 43.0,
    aligned = 67:
        identities = 13,
        positives = 25,
        mismatches = 54.
    gaps = 4:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 4:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 4:
                open_internal_deletions = 2,
                extend_internal_deletions = 2;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 4)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 4)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 4)
        self.assertEqual(counts.gaps, 4)
        self.assertEqual(counts.aligned, 67)
        self.assertEqual(counts.identities, 13)
        self.assertEqual(counts.mismatches, 54)
        self.assertEqual(counts.positives, 25)
        with self.assertRaises(StopIteration):
            next(alignments)

    def test_m8CC(self):
        # Alignment file obtained by running
        # fasta36 -q -m 8CB seq/mgstm1.aa seq/prot_test.lseg
        # in the fasta36 source distribution
        path = "Fasta/protein_m8CC.txt"
        alignments = Align.parse(path, "tabular")
        self.assertEqual(
            alignments.metadata["Command line"],
            "fasta36 -q -m 8CC seq/mgstm1.aa seq/prot_test.lseg",
        )
        self.assertEqual(alignments.metadata["Program"], "FASTA")
        self.assertEqual(alignments.metadata["Version"], "36.3.8h May, 2020")
        self.assertEqual(alignments.metadata["Database"], "seq/prot_test.lseg")
        # sp|P10649|GSTM1_MOUSE   sp|P09488|GSTM1_HUMAN
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 77.98)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 218)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 218)
        self.assertEqual(alignment.shape, (2, 218 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P09488|GSTM1_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 48)
        self.assertAlmostEqual(alignment.annotations["evalue"], 7.6e-83, places=84)
        self.assertAlmostEqual(alignment.annotations["bit score"], 291.9)
        self.assertEqual(
            str(alignment),
            """\
sp|P09488         0 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649         0 ????????????????????????????????????????????????????????????

sp|P09488        60 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649        60 ????????????????????????????????????????????????????????????

sp|P09488       120 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp|P10649       120 ????????????????????????????????????????????????????????????

sp|P09488       180 ?????????????????????????????????????? 218
                180 |||||||||||||||||||||||||||||||||||||| 218
sp|P10649       180 ?????????????????????????????????????? 218
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[0, 218], [0, 218]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 218)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "MPMILGYWDIRGLAHAIRLLLEYTDSSYEEKKYTMGDAPDYDRSQWLNEKFKLGLDFPNLPYLIDGAHKITQSNAILCYIARKHNLCGETEEEKIRVDILENQTMDNHMQLGMICYNPEFEKLKPKYLEELPEKLKLYSEFLGKRPWFAGNKITFVDFLVYDVLDLHRIFEPKCLDAFPNLKDFISRFEGLEKISAYMKSSRFLPRPVFSKMAVWGNK",
        )
        self.assertEqual(
            alignment[1],
            "MPMILGYWNVRGLTHPIRMLLEYTDSSYDEKRYTMGDAPDFDRSQWLNEKFKLGLDFPNLPYLIDGSHKITQSNAILRYLARKHHLDGETEEERIRADIVENQVMDTRMQLIMLCYNPDFEKQKPEFLKTIPEKMKLYSEFLGKRPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKKISAYMKSSRYIATPIFSKMAHWSNK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P00502|GSTA1_RAT
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['M', 'P', 'M', 'I', 'L', 'G', 'Y', 'W', 'D', 'I', 'R', 'G', 'L',
           'A', 'H', 'A', 'I', 'R', 'L', 'L', 'L', 'E', 'Y', 'T', 'D', 'S',
           'S', 'Y', 'E', 'E', 'K', 'K', 'Y', 'T', 'M', 'G', 'D', 'A', 'P',
           'D', 'Y', 'D', 'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K',
           'L', 'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D',
           'G', 'A', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'C',
           'Y', 'I', 'A', 'R', 'K', 'H', 'N', 'L', 'C', 'G', 'E', 'T', 'E',
           'E', 'E', 'K', 'I', 'R', 'V', 'D', 'I', 'L', 'E', 'N', 'Q', 'T',
           'M', 'D', 'N', 'H', 'M', 'Q', 'L', 'G', 'M', 'I', 'C', 'Y', 'N',
           'P', 'E', 'F', 'E', 'K', 'L', 'K', 'P', 'K', 'Y', 'L', 'E', 'E',
           'L', 'P', 'E', 'K', 'L', 'K', 'L', 'Y', 'S', 'E', 'F', 'L', 'G',
           'K', 'R', 'P', 'W', 'F', 'A', 'G', 'N', 'K', 'I', 'T', 'F', 'V',
           'D', 'F', 'L', 'V', 'Y', 'D', 'V', 'L', 'D', 'L', 'H', 'R', 'I',
           'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A', 'F', 'P', 'N', 'L', 'K',
           'D', 'F', 'I', 'S', 'R', 'F', 'E', 'G', 'L', 'E', 'K', 'I', 'S',
           'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'F', 'L', 'P', 'R', 'P', 'V',
           'F', 'S', 'K', 'M', 'A', 'V', 'W', 'G', 'N', 'K'],
          ['M', 'P', 'M', 'I', 'L', 'G', 'Y', 'W', 'N', 'V', 'R', 'G', 'L',
           'T', 'H', 'P', 'I', 'R', 'M', 'L', 'L', 'E', 'Y', 'T', 'D', 'S',
           'S', 'Y', 'D', 'E', 'K', 'R', 'Y', 'T', 'M', 'G', 'D', 'A', 'P',
           'D', 'F', 'D', 'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K',
           'L', 'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D',
           'G', 'S', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'R',
           'Y', 'L', 'A', 'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E',
           'E', 'E', 'R', 'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V',
           'M', 'D', 'T', 'R', 'M', 'Q', 'L', 'I', 'M', 'L', 'C', 'Y', 'N',
           'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P', 'E', 'F', 'L', 'K', 'T',
           'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E', 'F', 'L', 'G',
           'K', 'R', 'P', 'W', 'F', 'A', 'G', 'D', 'K', 'V', 'T', 'Y', 'V',
           'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L', 'D', 'Q', 'Y', 'R', 'M',
           'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A', 'F', 'P', 'N', 'L', 'R',
           'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G', 'L', 'K', 'K', 'I', 'S',
           'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'Y', 'I', 'A', 'T', 'P', 'I',
           'F', 'S', 'K', 'M', 'A', 'H', 'W', 'S', 'N', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 967.0; 218 aligned letters; 170 identities; 48 mismatches; 201 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 967.0,
    aligned = 218:
        identities = 170,
        positives = 201,
        mismatches = 48.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 218)
        self.assertEqual(counts.identities, 170)
        self.assertEqual(counts.mismatches, 48)
        self.assertEqual(counts.positives, 201)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 29.76)
        self.assertEqual(alignment.annotations["gap opens"], 18)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 205)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 205)
        self.assertEqual(alignment.shape, (2, 205 + 18))
        self.assertEqual(alignment.sequences[0].id, "sp|P00502|GSTA1_RAT")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 144)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.4e-14, places=15)
        self.assertAlmostEqual(alignment.annotations["bit score"], 63.5)
        self.assertEqual(
            str(alignment),
            """\
sp|P00502         5 ????????????????????????????---------???????????????????????
                  0 ||||||||||||||||||||||||||||---------|||||||||||||--||||||||
sp|P10649         3 ??????????????????????????????????????????????????--????????

sp|P00502        56 ??????-?????????????????????????????????????????????????????
                 60 ||-|||-|||||||||||||||||||||||||||||||||||||||-|||||||||||||
sp|P10649        61 ??-???????????????????????????????????????????-?????????????

sp|P00502       115 ????????????????????????????????????????????????????????????
                120 ||||||||||--|||||||||||||||--|||||||||||||||||||||||||||||||
sp|P10649       119 ??????????--???????????????--???????????????????????????????

sp|P00502       175 ??????????????????????????????????????????? 218
                180 ||||||||||||||||||||||||||||||||||||||||||| 223
sp|P10649       175 ??????????????????????????????????????????? 218
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 5,  33,  33,  46,  48,  58,  59,  62,
                           62, 101, 102, 125, 127, 142, 144, 218],
                          [ 3,  31,  40,  53,  53,  63,  63,  66,
                           67, 106, 106, 129, 129, 144, 144, 218]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 218)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "VLHYFNARGRMECIRWLLAAAGVEFDEK---------FIQSPEDLEKLKKDGNLMFDQVPMVEIDG-MKLAQTRAILNYIATKYDLYGKDMKERALIDMYTEGILDLTEMIMQLVICPPDQKEAKTALAKDRTKNRYLPAFEKVLKSHGQDYLVGNRLTRVDIHLLELLLYVEEFDASLLTSFPLLKAFKSRISSLPNVKKFLQPGSQRKLPVDAKQIEEARK",
        )
        self.assertEqual(
            alignment[1],
            "ILGYWNVRGLTHPIRMLLEYTDSSYDEKRYTMGDAPDFDRSQWLNEKFKL--GLDFPNLPYL-IDGSHKITQSNAILRYLARKHHLDGETEEERIRADIVENQVMD-TRMQLIMLCYNPDFEKQKPEFLK--TIPEKMKLYSEFLGK--RPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKKISAYMKSSRYIATPIFSKMAHWSNK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P69905|HBA_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['V', 'L', 'H', 'Y', 'F', 'N', 'A', 'R', 'G', 'R', 'M', 'E', 'C',
           'I', 'R', 'W', 'L', 'L', 'A', 'A', 'A', 'G', 'V', 'E', 'F', 'D',
           'E', 'K', '-', '-', '-', '-', '-', '-', '-', '-', '-', 'F', 'I',
           'Q', 'S', 'P', 'E', 'D', 'L', 'E', 'K', 'L', 'K', 'K', 'D', 'G',
           'N', 'L', 'M', 'F', 'D', 'Q', 'V', 'P', 'M', 'V', 'E', 'I', 'D',
           'G', '-', 'M', 'K', 'L', 'A', 'Q', 'T', 'R', 'A', 'I', 'L', 'N',
           'Y', 'I', 'A', 'T', 'K', 'Y', 'D', 'L', 'Y', 'G', 'K', 'D', 'M',
           'K', 'E', 'R', 'A', 'L', 'I', 'D', 'M', 'Y', 'T', 'E', 'G', 'I',
           'L', 'D', 'L', 'T', 'E', 'M', 'I', 'M', 'Q', 'L', 'V', 'I', 'C',
           'P', 'P', 'D', 'Q', 'K', 'E', 'A', 'K', 'T', 'A', 'L', 'A', 'K',
           'D', 'R', 'T', 'K', 'N', 'R', 'Y', 'L', 'P', 'A', 'F', 'E', 'K',
           'V', 'L', 'K', 'S', 'H', 'G', 'Q', 'D', 'Y', 'L', 'V', 'G', 'N',
           'R', 'L', 'T', 'R', 'V', 'D', 'I', 'H', 'L', 'L', 'E', 'L', 'L',
           'L', 'Y', 'V', 'E', 'E', 'F', 'D', 'A', 'S', 'L', 'L', 'T', 'S',
           'F', 'P', 'L', 'L', 'K', 'A', 'F', 'K', 'S', 'R', 'I', 'S', 'S',
           'L', 'P', 'N', 'V', 'K', 'K', 'F', 'L', 'Q', 'P', 'G', 'S', 'Q',
           'R', 'K', 'L', 'P', 'V', 'D', 'A', 'K', 'Q', 'I', 'E', 'E', 'A',
           'R', 'K'],
          ['I', 'L', 'G', 'Y', 'W', 'N', 'V', 'R', 'G', 'L', 'T', 'H', 'P',
           'I', 'R', 'M', 'L', 'L', 'E', 'Y', 'T', 'D', 'S', 'S', 'Y', 'D',
           'E', 'K', 'R', 'Y', 'T', 'M', 'G', 'D', 'A', 'P', 'D', 'F', 'D',
           'R', 'S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K', 'L', '-', '-',
           'G', 'L', 'D', 'F', 'P', 'N', 'L', 'P', 'Y', 'L', '-', 'I', 'D',
           'G', 'S', 'H', 'K', 'I', 'T', 'Q', 'S', 'N', 'A', 'I', 'L', 'R',
           'Y', 'L', 'A', 'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E',
           'E', 'E', 'R', 'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V',
           'M', 'D', '-', 'T', 'R', 'M', 'Q', 'L', 'I', 'M', 'L', 'C', 'Y',
           'N', 'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P', 'E', 'F', 'L', 'K',
           '-', '-', 'T', 'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E',
           'F', 'L', 'G', 'K', '-', '-', 'R', 'P', 'W', 'F', 'A', 'G', 'D',
           'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L',
           'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A',
           'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G',
           'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K', 'S', 'S', 'R', 'Y',
           'I', 'A', 'T', 'P', 'I', 'F', 'S', 'K', 'M', 'A', 'H', 'W', 'S',
           'N', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 257.0; 205 aligned letters; 61 identities; 144 mismatches; 102 positives; 18 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 257.0,
    aligned = 205:
        identities = 61,
        positives = 102,
        mismatches = 144.
    gaps = 18:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 18:
            internal_insertions = 10:
                open_internal_insertions = 2,
                extend_internal_insertions = 8;
            internal_deletions = 8:
                open_internal_deletions = 5,
                extend_internal_deletions = 3;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 10)
        self.assertEqual(counts.internal_deletions, 8)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 18)
        self.assertEqual(counts.insertions, 10)
        self.assertEqual(counts.deletions, 8)
        self.assertEqual(counts.gaps, 18)
        self.assertEqual(counts.aligned, 205)
        self.assertEqual(counts.identities, 61)
        self.assertEqual(counts.mismatches, 144)
        self.assertEqual(counts.positives, 102)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 27.03)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 37)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 37)
        self.assertEqual(alignment.shape, (2, 37 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P69905|HBA_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 27)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.15)
        self.assertAlmostEqual(alignment.annotations["bit score"], 21.2)
        self.assertEqual(
            str(alignment),
            """\
sp|P69905        35 ?????????????-?????????????????????????  73
                  0 |||||||||||||-||||||||||-||||||||||||||  39
sp|P10649       176 ????????????????????????-?????????????? 214
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 35,  48,  48,  58,  59,  73],
                          [176, 189, 190, 200, 200, 214]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 73)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "SFPTTKTYFPHFD-LSHGSAQVKGHGKKVADALTNAVAH")
        self.assertEqual(alignment[1], "AFPNLRDFLARFEGLKKISAYMKS-SRYIATPIFSKMAH")
        # sp|P10649|GSTM1_MOUSE   sp|P00517|KAPCA_BOVIN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['S', 'F', 'P', 'T', 'T', 'K', 'T', 'Y', 'F', 'P', 'H', 'F', 'D',
           '-', 'L', 'S', 'H', 'G', 'S', 'A', 'Q', 'V', 'K', 'G', 'H', 'G',
           'K', 'K', 'V', 'A', 'D', 'A', 'L', 'T', 'N', 'A', 'V', 'A', 'H'],
          ['A', 'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E',
           'G', 'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K', 'S', '-', 'S',
           'R', 'Y', 'I', 'A', 'T', 'P', 'I', 'F', 'S', 'K', 'M', 'A', 'H']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 54.0; 37 aligned letters; 10 identities; 27 mismatches; 20 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 54.0,
    aligned = 37:
        identities = 10,
        positives = 20,
        mismatches = 27.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 37)
        self.assertEqual(counts.identities, 10)
        self.assertEqual(counts.mismatches, 27)
        self.assertEqual(counts.positives, 20)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 24.29)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 70)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 70)
        self.assertEqual(alignment.shape, (2, 70 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P00517|KAPCA_BOVIN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 53)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.2)
        self.assertAlmostEqual(alignment.annotations["bit score"], 19.4)
        self.assertEqual(
            str(alignment),
            """\
sp|P00517       228 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||--||||||||||||
sp|P10649       136 ??????????????????????????????????????????????--????????????

sp|P00517       288 ???????????? 300
                 60 ||||||||||||  72
sp|P10649       194 ???????????? 206
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[228, 274, 276, 300],
                          [136, 182, 182, 206]]),
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 300)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "IYEMAAGYPPFFADQPIQIYEKIVSGKVRFPSHFSSDLKDLLRNLLQVDLTKRFGNLKNGVNDIKNHKWFAT",
        )
        self.assertEqual(
            alignment[1],
            "LYSEFLGKRPWFAGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLR--DFLARFEGLKKISAYMKSSRYIAT",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P14960|RBS_GUITH
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['I', 'Y', 'E', 'M', 'A', 'A', 'G', 'Y', 'P', 'P', 'F', 'F', 'A',
           'D', 'Q', 'P', 'I', 'Q', 'I', 'Y', 'E', 'K', 'I', 'V', 'S', 'G',
           'K', 'V', 'R', 'F', 'P', 'S', 'H', 'F', 'S', 'S', 'D', 'L', 'K',
           'D', 'L', 'L', 'R', 'N', 'L', 'L', 'Q', 'V', 'D', 'L', 'T', 'K',
           'R', 'F', 'G', 'N', 'L', 'K', 'N', 'G', 'V', 'N', 'D', 'I', 'K',
           'N', 'H', 'K', 'W', 'F', 'A', 'T'],
          ['L', 'Y', 'S', 'E', 'F', 'L', 'G', 'K', 'R', 'P', 'W', 'F', 'A',
           'G', 'D', 'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D',
           'I', 'L', 'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L',
           'D', 'A', 'F', 'P', 'N', 'L', 'R', '-', '-', 'D', 'F', 'L', 'A',
           'R', 'F', 'E', 'G', 'L', 'K', 'K', 'I', 'S', 'A', 'Y', 'M', 'K',
           'S', 'S', 'R', 'Y', 'I', 'A', 'T']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 49.0; 70 aligned letters; 17 identities; 53 mismatches; 27 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 49.0,
    aligned = 70:
        identities = 17,
        positives = 27,
        mismatches = 53.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 2:
                open_internal_deletions = 1,
                extend_internal_deletions = 1;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 2)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 2)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 70)
        self.assertEqual(counts.identities, 17)
        self.assertEqual(counts.mismatches, 53)
        self.assertEqual(counts.positives, 27)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 57.14)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 7)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 7)
        self.assertEqual(alignment.shape, (2, 7 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P14960|RBS_GUITH")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 3)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.5)
        self.assertAlmostEqual(alignment.annotations["bit score"], 17.8)
        self.assertEqual(
            str(alignment),
            """\
sp|P14960        46 ??????? 53
                  0 |||||||  7
sp|P10649         6 ??????? 13
""",
        )
        self.assertTrue(
            np.array_equal(alignment.coordinates, np.array([[46, 53], [6, 13]]))
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 53)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "YWDLWGL")
        self.assertEqual(alignment[1], "YWNVRGL")
        # sp|P10649|GSTM1_MOUSE   sp|P01593|KV101_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['Y', 'W', 'D', 'L', 'W', 'G', 'L'],
          ['Y', 'W', 'N', 'V', 'R', 'G', 'L']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 27.0; 7 aligned letters; 4 identities; 3 mismatches; 6 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 27.0,
    aligned = 7:
        identities = 4,
        positives = 6,
        mismatches = 3.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 7)
        self.assertEqual(counts.identities, 4)
        self.assertEqual(counts.mismatches, 3)
        self.assertEqual(counts.positives, 6)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 45.00)
        self.assertEqual(alignment.annotations["gap opens"], 10)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 40)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 40)
        self.assertEqual(alignment.shape, (2, 40 + 10))
        self.assertEqual(alignment.sequences[0].id, "sp|P01593|KV101_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 22)
        self.assertAlmostEqual(alignment.annotations["evalue"], 2.4)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.7)
        self.assertEqual(
            str(alignment),
            """\
sp|P01593        15 ????????????????????????????????????-?????????????  64
                  0 ||||||||||||||---||||||||---||||--||-|||||||-|||||  50
sp|P10649       149 ??????????????---????????---????--??????????-????? 190
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[15,  29,  32,  40,  43,  47,
                           49,  51,  51,  58,  59,  64],
                         [149, 163, 163, 171, 171, 175,
                          175, 177, 178, 185, 185, 190]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 64)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0], "GDRVTITCQASQDINHYLNWYQQGPKKAPKILIYDA-SNLETGVPSRFSG"
        )
        self.assertEqual(
            alignment[1], "GDKVTYVDFLAYDI---LDQYRMFE---PKCL--DAFPNLRDFL-ARFEG"
        )
        # sp|P10649|GSTM1_MOUSE   sp|P99998|CYC_PANTR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'D', 'R', 'V', 'T', 'I', 'T', 'C', 'Q', 'A', 'S', 'Q', 'D',
           'I', 'N', 'H', 'Y', 'L', 'N', 'W', 'Y', 'Q', 'Q', 'G', 'P', 'K',
           'K', 'A', 'P', 'K', 'I', 'L', 'I', 'Y', 'D', 'A', '-', 'S', 'N',
           'L', 'E', 'T', 'G', 'V', 'P', 'S', 'R', 'F', 'S', 'G'],
          ['G', 'D', 'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D',
           'I', '-', '-', '-', 'L', 'D', 'Q', 'Y', 'R', 'M', 'F', 'E', '-',
           '-', '-', 'P', 'K', 'C', 'L', '-', '-', 'D', 'A', 'F', 'P', 'N',
           'L', 'R', 'D', 'F', 'L', '-', 'A', 'R', 'F', 'E', 'G']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 81.0; 40 aligned letters; 18 identities; 22 mismatches; 24 positives; 10 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 81.0,
    aligned = 40:
        identities = 18,
        positives = 24,
        mismatches = 22.
    gaps = 10:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 10:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 9:
                open_internal_deletions = 4,
                extend_internal_deletions = 5;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 9)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 10)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 9)
        self.assertEqual(counts.gaps, 10)
        self.assertEqual(counts.aligned, 40)
        self.assertEqual(counts.identities, 18)
        self.assertEqual(counts.mismatches, 22)
        self.assertEqual(counts.positives, 24)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 31.03)
        self.assertEqual(alignment.annotations["gap opens"], 10)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 58)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 58)
        self.assertEqual(alignment.shape, (2, 58 + 10))
        self.assertEqual(alignment.sequences[0].id, "sp|P99998|CYC_PANTR")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 40)
        self.assertAlmostEqual(alignment.annotations["evalue"], 2.7)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.5)
        self.assertEqual(
            str(alignment),
            """\
sp|P99998        27 ???????????????????????????????-??????????-?????--?????????-
                  0 ||||||||||||||||||||---||||||||-||||||||||-|||||--|||||||||-
sp|P10649       128 ????????????????????---?????????????????????????????????????

sp|P99998        82 --??????  88
                 60 --||||||  68
sp|P10649       185 ???????? 193
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 27,  47,  50,  58,  58,  68,
                            68,  73,  73,  82,  82,  88],
                          [128, 148, 148, 156, 157, 167,
                           168, 173, 175, 184, 187, 193]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 88)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "KTGPNLHGLFGRKTGQAPGYSYTAANKNKGI-IWGEDTLMEY-LENPK--KYIPGTKMI---FVGIKK",
        )
        self.assertEqual(
            alignment[1],
            "KTIPEKMKLYSEFLGKRPWF---AGDKVTYVDFLAYDILDQYRMFEPKCLDAFPNLRDFLARFEGLKK",
        )
        # sp|P10649|GSTM1_MOUSE   sp|P02585|TNNC2_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['K', 'T', 'G', 'P', 'N', 'L', 'H', 'G', 'L', 'F', 'G', 'R', 'K',
           'T', 'G', 'Q', 'A', 'P', 'G', 'Y', 'S', 'Y', 'T', 'A', 'A', 'N',
           'K', 'N', 'K', 'G', 'I', '-', 'I', 'W', 'G', 'E', 'D', 'T', 'L',
           'M', 'E', 'Y', '-', 'L', 'E', 'N', 'P', 'K', '-', '-', 'K', 'Y',
           'I', 'P', 'G', 'T', 'K', 'M', 'I', '-', '-', '-', 'F', 'V', 'G',
           'I', 'K', 'K'],
          ['K', 'T', 'I', 'P', 'E', 'K', 'M', 'K', 'L', 'Y', 'S', 'E', 'F',
           'L', 'G', 'K', 'R', 'P', 'W', 'F', '-', '-', '-', 'A', 'G', 'D',
           'K', 'V', 'T', 'Y', 'V', 'D', 'F', 'L', 'A', 'Y', 'D', 'I', 'L',
           'D', 'Q', 'Y', 'R', 'M', 'F', 'E', 'P', 'K', 'C', 'L', 'D', 'A',
           'F', 'P', 'N', 'L', 'R', 'D', 'F', 'L', 'A', 'R', 'F', 'E', 'G',
           'L', 'K', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 76.0; 58 aligned letters; 18 identities; 40 mismatches; 27 positives; 10 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 58:
        identities = 18,
        positives = 27,
        mismatches = 40.
    gaps = 10:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 10:
            internal_insertions = 7:
                open_internal_insertions = 4,
                extend_internal_insertions = 3;
            internal_deletions = 3:
                open_internal_deletions = 1,
                extend_internal_deletions = 2;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 7)
        self.assertEqual(counts.internal_deletions, 3)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 10)
        self.assertEqual(counts.insertions, 7)
        self.assertEqual(counts.deletions, 3)
        self.assertEqual(counts.gaps, 10)
        self.assertEqual(counts.aligned, 58)
        self.assertEqual(counts.identities, 18)
        self.assertEqual(counts.mismatches, 40)
        self.assertEqual(counts.positives, 27)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 31.11)
        self.assertEqual(alignment.annotations["gap opens"], 9)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 45)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 45)
        self.assertEqual(alignment.shape, (2, 45 + 9))
        self.assertEqual(alignment.sequences[0].id, "sp|P02585|TNNC2_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 31)
        self.assertAlmostEqual(alignment.annotations["evalue"], 3.8)
        self.assertAlmostEqual(alignment.annotations["bit score"], 16.5)
        self.assertEqual(
            str(alignment),
            """\
sp|P02585        12 ??????????????----???????????????????????????????????? 62
                  0 ||||||||||||||----||||||||||--|||||||||||---|||||||||| 54
sp|P10649        43 ????????????????????????????--???????????---?????????? 92
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[12, 26, 26, 36, 38, 49, 52, 62],
                          [43, 57, 61, 71, 71, 82, 82, 92]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 62)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0], "SEEMIAEFKAAFDM----FDADGGGDISVKELGTVMRMLGQTPTKEELDAIIEE"
        )
        self.assertEqual(
            alignment[1], "SQWLNEKFKLGLDFPNLPYLIDGSHKIT--QSNAILRYLAR---KHHLDGETEE"
        )
        # sp|P10649|GSTM1_MOUSE   sp|P60615|NXL1A_BUNMU
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['S', 'E', 'E', 'M', 'I', 'A', 'E', 'F', 'K', 'A', 'A', 'F', 'D',
           'M', '-', '-', '-', '-', 'F', 'D', 'A', 'D', 'G', 'G', 'G', 'D',
           'I', 'S', 'V', 'K', 'E', 'L', 'G', 'T', 'V', 'M', 'R', 'M', 'L',
           'G', 'Q', 'T', 'P', 'T', 'K', 'E', 'E', 'L', 'D', 'A', 'I', 'I',
           'E', 'E'],
          ['S', 'Q', 'W', 'L', 'N', 'E', 'K', 'F', 'K', 'L', 'G', 'L', 'D',
           'F', 'P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D', 'G', 'S', 'H', 'K',
           'I', 'T', '-', '-', 'Q', 'S', 'N', 'A', 'I', 'L', 'R', 'Y', 'L',
           'A', 'R', '-', '-', '-', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T',
           'E', 'E']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 65.0; 45 aligned letters; 14 identities; 31 mismatches; 23 positives; 9 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 65.0,
    aligned = 45:
        identities = 14,
        positives = 23,
        mismatches = 31.
    gaps = 9:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 9:
            internal_insertions = 4:
                open_internal_insertions = 1,
                extend_internal_insertions = 3;
            internal_deletions = 5:
                open_internal_deletions = 2,
                extend_internal_deletions = 3;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 4)
        self.assertEqual(counts.internal_deletions, 5)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 9)
        self.assertEqual(counts.insertions, 4)
        self.assertEqual(counts.deletions, 5)
        self.assertEqual(counts.gaps, 9)
        self.assertEqual(counts.aligned, 45)
        self.assertEqual(counts.identities, 14)
        self.assertEqual(counts.mismatches, 31)
        self.assertEqual(counts.positives, 23)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 66.67)
        self.assertEqual(alignment.annotations["gap opens"], 2)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 9)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 9)
        self.assertEqual(alignment.shape, (2, 9 + 2))
        self.assertEqual(alignment.sequences[0].id, "sp|P60615|NXL1A_BUNMU")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 3)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.2)
        self.assertAlmostEqual(alignment.annotations["bit score"], 15.6)
        self.assertEqual(
            str(alignment),
            """\
sp|P60615        85 ?-???-?????  94
                  0 |-|||-|||||  11
sp|P10649       114 ??????????? 125
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[ 85,  86,  86,  89,  89,  94],
                          [114, 115, 116, 119, 120, 125]]),
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 94)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "C-NPH-PKQRP")
        self.assertEqual(alignment[1], "CYNPDFEKQKP")
        # sp|P10649|GSTM1_MOUSE   sp|P03435|HEMA_I75A3
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', '-', 'N', 'P', 'H', '-', 'P', 'K', 'Q', 'R', 'P'],
          ['C', 'Y', 'N', 'P', 'D', 'F', 'E', 'K', 'Q', 'K', 'P']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 39.0; 9 aligned letters; 6 identities; 3 mismatches; 7 positives; 2 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 39.0,
    aligned = 9:
        identities = 6,
        positives = 7,
        mismatches = 3.
    gaps = 2:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 2:
            internal_insertions = 2:
                open_internal_insertions = 2,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 2)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 2)
        self.assertEqual(counts.insertions, 2)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 2)
        self.assertEqual(counts.aligned, 9)
        self.assertEqual(counts.identities, 6)
        self.assertEqual(counts.mismatches, 3)
        self.assertEqual(counts.positives, 7)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 28.95)
        self.assertEqual(alignment.annotations["gap opens"], 1)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 38)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 38)
        self.assertEqual(alignment.shape, (2, 38 + 1))
        self.assertEqual(alignment.sequences[0].id, "sp|P03435|HEMA_I75A3")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 27)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.4)
        self.assertAlmostEqual(alignment.annotations["bit score"], 18.1)
        self.assertEqual(
            str(alignment),
            """\
sp|P03435       398 ??????????????????????????????????????? 437
                  0 ||||||||||-||||||||||||||||||||||||||||  39
sp|P10649        73 ??????????-???????????????????????????? 111
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[398, 408, 409, 437],
                          [ 73,  83,  83, 111]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 437)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "NRVIEKTNEKFHQIEKEFSEVEGRIQDLEKYVEDTKIDL")
        self.assertEqual(alignment[1], "NAILRYLARK-HHLDGETEEERIRADIVENQVMDTRMQL")
        # sp|P10649|GSTM1_MOUSE   sp|P00193|FER_PEPAS
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['N', 'R', 'V', 'I', 'E', 'K', 'T', 'N', 'E', 'K', 'F', 'H', 'Q',
           'I', 'E', 'K', 'E', 'F', 'S', 'E', 'V', 'E', 'G', 'R', 'I', 'Q',
           'D', 'L', 'E', 'K', 'Y', 'V', 'E', 'D', 'T', 'K', 'I', 'D', 'L'],
          ['N', 'A', 'I', 'L', 'R', 'Y', 'L', 'A', 'R', 'K', '-', 'H', 'H',
           'L', 'D', 'G', 'E', 'T', 'E', 'E', 'E', 'R', 'I', 'R', 'A', 'D',
           'I', 'V', 'E', 'N', 'Q', 'V', 'M', 'D', 'T', 'R', 'M', 'Q', 'L']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 48.0; 38 aligned letters; 11 identities; 27 mismatches; 18 positives; 1 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 48.0,
    aligned = 38:
        identities = 11,
        positives = 18,
        mismatches = 27.
    gaps = 1:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 1:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 1)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 1)
        self.assertEqual(counts.aligned, 38)
        self.assertEqual(counts.identities, 11)
        self.assertEqual(counts.mismatches, 27)
        self.assertEqual(counts.positives, 18)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 50.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 4)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 4)
        self.assertEqual(alignment.shape, (2, 4 + 0))
        self.assertEqual(alignment.sequences[0].id, "sp|P00193|FER_PEPAS")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.4)
        self.assertAlmostEqual(alignment.annotations["bit score"], 14.7)
        self.assertEqual(
            str(alignment),
            """\
sp|P00193        14 ????  18
                  0 ||||   4
sp|P10649       170 ???? 174
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[14, 18], [170, 174]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 18)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "KPEC")
        self.assertEqual(alignment[1], "EPKC")
        # sp|P10649|GSTM1_MOUSE   sp|P01834|IGKC_HUMAN
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['K', 'P', 'E', 'C'],
          ['E', 'P', 'K', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 18.0; 4 aligned letters; 2 identities; 2 mismatches; 4 positives; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 18.0,
    aligned = 4:
        identities = 2,
        positives = 4,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 4)
        self.assertEqual(counts.identities, 2)
        self.assertEqual(counts.mismatches, 2)
        self.assertEqual(counts.positives, 4)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 19.40)
        self.assertEqual(alignment.annotations["gap opens"], 4)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 67)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 67)
        self.assertEqual(alignment.shape, (2, 67 + 4))
        self.assertEqual(alignment.sequences[0].id, "sp|P01834|IGKC_HUMAN")
        self.assertEqual(alignment.sequences[1].id, "sp|P10649|GSTM1_MOUSE")
        self.assertEqual(alignment.annotations["mismatches"], 54)
        self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
        self.assertAlmostEqual(alignment.annotations["bit score"], 14.9)
        self.assertEqual(
            str(alignment),
            """\
sp|P01834        11 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||--||||||||||||||||||||||||||||||||||||||||--||
sp|P10649        57 ??????????????--????????????????????????????????????????--??

sp|P01834        71 ???????????  82
                 60 |||||||||||  71
sp|P10649       113 ??????????? 124
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[11, 25, 27,  67,  69,  82],
                          [57, 71, 71, 111, 111, 124]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 82)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "PSDEQLKSGTASVVCLLNNFYPREAKVQWKVDNALQSGNSQESVTEQDSKDSTYSLSSTLTLSKADYEKHK",
        )
        self.assertEqual(
            alignment[1],
            "PNLPYLIDGSHKIT--QSNAILRYLARKHHLDGETEEERIRADIVENQVMDTRMQL--IMLCYNPDFEKQK",
        )
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['P', 'S', 'D', 'E', 'Q', 'L', 'K', 'S', 'G', 'T', 'A', 'S', 'V',
           'V', 'C', 'L', 'L', 'N', 'N', 'F', 'Y', 'P', 'R', 'E', 'A', 'K',
           'V', 'Q', 'W', 'K', 'V', 'D', 'N', 'A', 'L', 'Q', 'S', 'G', 'N',
           'S', 'Q', 'E', 'S', 'V', 'T', 'E', 'Q', 'D', 'S', 'K', 'D', 'S',
           'T', 'Y', 'S', 'L', 'S', 'S', 'T', 'L', 'T', 'L', 'S', 'K', 'A',
           'D', 'Y', 'E', 'K', 'H', 'K'],
          ['P', 'N', 'L', 'P', 'Y', 'L', 'I', 'D', 'G', 'S', 'H', 'K', 'I',
           'T', '-', '-', 'Q', 'S', 'N', 'A', 'I', 'L', 'R', 'Y', 'L', 'A',
           'R', 'K', 'H', 'H', 'L', 'D', 'G', 'E', 'T', 'E', 'E', 'E', 'R',
           'I', 'R', 'A', 'D', 'I', 'V', 'E', 'N', 'Q', 'V', 'M', 'D', 'T',
           'R', 'M', 'Q', 'L', '-', '-', 'I', 'M', 'L', 'C', 'Y', 'N', 'P',
           'D', 'F', 'E', 'K', 'Q', 'K']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts(substitution_matrix)
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (substitution score = 43.0; 67 aligned letters; 13 identities; 54 mismatches; 25 positives; 4 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    substitution_score = 43.0,
    aligned = 67:
        identities = 13,
        positives = 25,
        mismatches = 54.
    gaps = 4:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 4:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 4:
                open_internal_deletions = 2,
                extend_internal_deletions = 2;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 4)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 4)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 4)
        self.assertEqual(counts.gaps, 4)
        self.assertEqual(counts.aligned, 67)
        self.assertEqual(counts.identities, 13)
        self.assertEqual(counts.mismatches, 54)
        self.assertEqual(counts.positives, 25)
        with self.assertRaises(StopIteration):
            next(alignments)


class TestFastaNucleotide(unittest.TestCase):
    query = Seq(
        "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGAGTAACAAGTAG"
    )

    filename = os.path.join("Fasta", "nucleotide_lib.fa")
    records = SeqIO.parse(filename, "fasta")
    targets = {record.id: record.seq.upper() for record in records}

    def test_m8CB(self):
        # Alignment file obtained by running
        # fasta36 -m 8CB seq/mgstm1.nt seq/gst.nlib
        # in the fasta36 source distribution
        path = "Fasta/nucleotide_m8CB.txt"
        alignments = Align.parse(path, "tabular")
        self.assertEqual(
            alignments.metadata["Command line"],
            "fasta36 -m 8CB seq/mgstm1.nt seq/gst.nlib",
        )
        self.assertEqual(alignments.metadata["Program"], "FASTA")
        self.assertEqual(alignments.metadata["Version"], "36.3.8h May, 2020")
        self.assertEqual(alignments.metadata["Database"], "seq/gst.nlib")
        # pGT875   pGT875
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 657)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 657)
        self.assertEqual(alignment.shape, (2, 657 + 0))
        self.assertEqual(alignment.sequences[0].id, "pGT875")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 3.6e-194, places=195)
        self.assertAlmostEqual(alignment.annotations["bit score"], 666.0)
        self.assertEqual(
            str(alignment),
            """\
pGT875           37 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875            0 ????????????????????????????????????????????????????????????

pGT875           97 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875           60 ????????????????????????????????????????????????????????????

pGT875          157 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          120 ????????????????????????????????????????????????????????????

pGT875          217 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          180 ????????????????????????????????????????????????????????????

pGT875          277 ????????????????????????????????????????????????????????????
                240 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          240 ????????????????????????????????????????????????????????????

pGT875          337 ????????????????????????????????????????????????????????????
                300 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          300 ????????????????????????????????????????????????????????????

pGT875          397 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          360 ????????????????????????????????????????????????????????????

pGT875          457 ????????????????????????????????????????????????????????????
                420 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          420 ????????????????????????????????????????????????????????????

pGT875          517 ????????????????????????????????????????????????????????????
                480 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          480 ????????????????????????????????????????????????????????????

pGT875          577 ????????????????????????????????????????????????????????????
                540 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          540 ????????????????????????????????????????????????????????????

pGT875          637 ????????????????????????????????????????????????????????? 694
                600 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 657
pGT875          600 ????????????????????????????????????????????????????????? 657
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[37, 694], [0, 657]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 694)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGAGTAACAAGTAG",
        )
        self.assertEqual(
            alignment[1],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGAGTAACAAGTAG",
        )
        # pGT875   RABGLTR
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (657 aligned letters; 657 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 657:
        identities = 657,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 657)
        self.assertEqual(counts.identities, 657)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 79.10)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 646)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 646)
        self.assertEqual(alignment.shape, (2, 646 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGLTR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 135)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.9e-118, places=119)
        self.assertAlmostEqual(alignment.annotations["bit score"], 414.4)
        self.assertEqual(
            str(alignment),
            """\
RABGLTR          33 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875            0 ????????????????????????????????????????????????????????????

RABGLTR          93 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875           60 ????????????????????????????????????????????????????????????

RABGLTR         153 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          120 ????????????????????????????????????????????????????????????

RABGLTR         213 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          180 ????????????????????????????????????????????????????????????

RABGLTR         273 ????????????????????????????????????????????????????????????
                240 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          240 ????????????????????????????????????????????????????????????

RABGLTR         333 ????????????????????????????????????????????????????????????
                300 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          300 ????????????????????????????????????????????????????????????

RABGLTR         393 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          360 ????????????????????????????????????????????????????????????

RABGLTR         453 ????????????????????????????????????????????????????????????
                420 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          420 ????????????????????????????????????????????????????????????

RABGLTR         513 ????????????????????????????????????????????????????????????
                480 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          480 ????????????????????????????????????????????????????????????

RABGLTR         573 ????????????????????????????????????????????????????????????
                540 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          540 ????????????????????????????????????????????????????????????

RABGLTR         633 ?????????????????????????????????????????????? 679
                600 |||||||||||||||||||||||||||||||||||||||||||||| 646
pGT875          600 ?????????????????????????????????????????????? 646
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[33, 679], [0, 646]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 679)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "ATGCCCATGACGCTGGGTTACTGGGACGTCCGTGGGCTGGCTCTGCCAATCCGCATGCTCCTGGAATACACGGACACCAGCTATGAGGAAAAGAAATACACCATGGGGGATGCTCCCAACTATGACCAAAGCAAGTGGCTGAGTGAGAAGTTCACCCTGGGCCTGGACTTTCCCAATCTGCCCTACCTAATTGATGGGACTCACAAGCTCACGCAGAGCAACGCCATCCTGCGCTACCTGGCCCGCAAGCACGGCCTGTGTGGGGAGACGGAAGAGGAGAGGATTCGCGTGGACATTCTGGAGAATCAGCTGATGGACAACCGCTTCCAACTTGTAAACGTCTGCTACAGTCCCGACTTTGAGAAGCTCAAGCCCGAGTACCTGAAGGGGCTCCCTGAGAAGCTGCAGCTGTACTCGCAGTTCCTGGGAAGCCTCCCCTGGTTCGCAGGGGACAAGATCACCTTCGCCGATTTCCTTGTCTACGACGTTCTTGACCAGAACCGGATATTTGTGCCTGGGTGCCTGGACGCGTTCCCAAACCTGAAGGACTTTCATGTCCGCTTTGAGGGCCTGCCGAAGATCTCTGCCTACATGAAGTCCAGCCGCTTTATCCGAGTCCCTGTGTTTTTAAAGAAGGCCACGTGGA",
        )
        self.assertEqual(
            alignment[1],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGA",
        )
        # pGT875   BTGST
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (646 aligned letters; 511 identities; 135 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 646:
        identities = 511,
        mismatches = 135.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 646)
        self.assertEqual(counts.identities, 511)
        self.assertEqual(counts.mismatches, 135)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 59.56)
        self.assertEqual(alignment.annotations["gap opens"], 21)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 413)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 413)
        self.assertEqual(alignment.shape, (2, 413 + 21))
        self.assertEqual(alignment.sequences[0].id, "BTGST")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 167)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.2e-07, places=8)
        self.assertAlmostEqual(alignment.annotations["bit score"], 46.4)
        self.assertEqual(
            str(alignment),
            """\
BTGST           227 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          175 ????????????????????????????????????????????????????????????

BTGST           287 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          235 ????????????????????????????????????????????????????????????

BTGST           347 ?????????????????????????????-?????????????????????????---??
                120 |||||||||||||||||||||||||||||-|||||||-|||||||||||||||||---||
pGT875          295 ?????????????????????????????????????-??????????????????????

BTGST           403 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
pGT875          354 ??????????????????????????????????????????????????????????--

BTGST           463 ????????????????????????????????????????????????????????????
                240 ---||||||-|||||||||||||--|||||||||||||----||||||||||||||||||
pGT875          412 ---??????-?????????????--?????????????----??????????????????

BTGST           523 ????????????????????--??????????????????????????????????????
                300 ||||||||||||--||||||--||||||||||||||||||||||||||||||||||||||
pGT875          462 ????????????--??????????????????????????????????????????????

BTGST           581 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          520 ????????????????????????????????????????????????????????????

BTGST           641 ?????????????? 655
                420 |||||||||||||| 434
pGT875          580 ?????????????? 594
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[227, 376, 376, 383, 384, 401, 401, 461, 466, 472,
                           473, 486, 488, 501, 505, 535, 537, 543, 543, 655],
                          [175, 324, 325, 332, 332, 349, 352, 412, 412, 418,
                           418, 431, 431, 444, 444, 474, 474, 480, 482, 594]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 655)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "AGCTCCCCAAGTTCCAGGACGGAGACCTCACGCTGTACCAGTCCAATGCCATCCTGCGGCACCTGGGCCGCACCCTCGGGCTGTATGGGAAGGACCAGCAGGAGGCGGCCCTGGTGGACATGGTGAATGACGGTGTAGAGGACCTTCGC-TGCAAATACGTCTCCCTCATTTACA---CCAACTACGAGGCGGGCAAGGAGGACTATGTGAAGGCGCTGCCCCAGCACCTGAAGCCTTTCGAGACCCTGCTGTCCCAGAACAAGGGTGGCCAGGCCTTCATCGTGGGCGACCAGATCTCCTTTGCGGACTACAACCTGCT--GGACCTGCTTCGGATTCACCAGGTCCTGGCCCCCAGCTGTCTGGACTCCTTCCCCCTGCTCTCAGCCTACGTGGCCCGTCTCAACTCCCGGCCCAAGCTCAAGGCCTTCCTG",
        )
        self.assertEqual(
            alignment[1],
            "ATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCT-CATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCT-----ACTCTG-AGTTCCTGGGCAA--GAGGCCATGGTTT----GCAGGGGACAAGGTCACCTATGTGGATTTC--CTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATG",
        )
        # pGT875   RABGSTB
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['A', 'G', 'C', 'T', 'C', 'C', 'C', 'C', 'A', 'A', 'G', 'T', 'T',
           'C', 'C', 'A', 'G', 'G', 'A', 'C', 'G', 'G', 'A', 'G', 'A', 'C',
           'C', 'T', 'C', 'A', 'C', 'G', 'C', 'T', 'G', 'T', 'A', 'C', 'C',
           'A', 'G', 'T', 'C', 'C', 'A', 'A', 'T', 'G', 'C', 'C', 'A', 'T',
           'C', 'C', 'T', 'G', 'C', 'G', 'G', 'C', 'A', 'C', 'C', 'T', 'G',
           'G', 'G', 'C', 'C', 'G', 'C', 'A', 'C', 'C', 'C', 'T', 'C', 'G',
           'G', 'G', 'C', 'T', 'G', 'T', 'A', 'T', 'G', 'G', 'G', 'A', 'A',
           'G', 'G', 'A', 'C', 'C', 'A', 'G', 'C', 'A', 'G', 'G', 'A', 'G',
           'G', 'C', 'G', 'G', 'C', 'C', 'C', 'T', 'G', 'G', 'T', 'G', 'G',
           'A', 'C', 'A', 'T', 'G', 'G', 'T', 'G', 'A', 'A', 'T', 'G', 'A',
           'C', 'G', 'G', 'T', 'G', 'T', 'A', 'G', 'A', 'G', 'G', 'A', 'C',
           'C', 'T', 'T', 'C', 'G', 'C', '-', 'T', 'G', 'C', 'A', 'A', 'A',
           'T', 'A', 'C', 'G', 'T', 'C', 'T', 'C', 'C', 'C', 'T', 'C', 'A',
           'T', 'T', 'T', 'A', 'C', 'A', '-', '-', '-', 'C', 'C', 'A', 'A',
           'C', 'T', 'A', 'C', 'G', 'A', 'G', 'G', 'C', 'G', 'G', 'G', 'C',
           'A', 'A', 'G', 'G', 'A', 'G', 'G', 'A', 'C', 'T', 'A', 'T', 'G',
           'T', 'G', 'A', 'A', 'G', 'G', 'C', 'G', 'C', 'T', 'G', 'C', 'C',
           'C', 'C', 'A', 'G', 'C', 'A', 'C', 'C', 'T', 'G', 'A', 'A', 'G',
           'C', 'C', 'T', 'T', 'T', 'C', 'G', 'A', 'G', 'A', 'C', 'C', 'C',
           'T', 'G', 'C', 'T', 'G', 'T', 'C', 'C', 'C', 'A', 'G', 'A', 'A',
           'C', 'A', 'A', 'G', 'G', 'G', 'T', 'G', 'G', 'C', 'C', 'A', 'G',
           'G', 'C', 'C', 'T', 'T', 'C', 'A', 'T', 'C', 'G', 'T', 'G', 'G',
           'G', 'C', 'G', 'A', 'C', 'C', 'A', 'G', 'A', 'T', 'C', 'T', 'C',
           'C', 'T', 'T', 'T', 'G', 'C', 'G', 'G', 'A', 'C', 'T', 'A', 'C',
           'A', 'A', 'C', 'C', 'T', 'G', 'C', 'T', '-', '-', 'G', 'G', 'A',
           'C', 'C', 'T', 'G', 'C', 'T', 'T', 'C', 'G', 'G', 'A', 'T', 'T',
           'C', 'A', 'C', 'C', 'A', 'G', 'G', 'T', 'C', 'C', 'T', 'G', 'G',
           'C', 'C', 'C', 'C', 'C', 'A', 'G', 'C', 'T', 'G', 'T', 'C', 'T',
           'G', 'G', 'A', 'C', 'T', 'C', 'C', 'T', 'T', 'C', 'C', 'C', 'C',
           'C', 'T', 'G', 'C', 'T', 'C', 'T', 'C', 'A', 'G', 'C', 'C', 'T',
           'A', 'C', 'G', 'T', 'G', 'G', 'C', 'C', 'C', 'G', 'T', 'C', 'T',
           'C', 'A', 'A', 'C', 'T', 'C', 'C', 'C', 'G', 'G', 'C', 'C', 'C',
           'A', 'A', 'G', 'C', 'T', 'C', 'A', 'A', 'G', 'G', 'C', 'C', 'T',
           'T', 'C', 'C', 'T', 'G'],
          ['A', 'T', 'C', 'T', 'G', 'C', 'C', 'T', 'T', 'A', 'C', 'T', 'T',
           'G', 'A', 'T', 'C', 'G', 'A', 'T', 'G', 'G', 'A', 'T', 'C', 'A',
           'C', 'A', 'C', 'A', 'A', 'G', 'A', 'T', 'C', 'A', 'C', 'C', 'C',
           'A', 'G', 'A', 'G', 'C', 'A', 'A', 'T', 'G', 'C', 'C', 'A', 'T',
           'C', 'C', 'T', 'G', 'C', 'G', 'C', 'T', 'A', 'C', 'C', 'T', 'T',
           'G', 'C', 'C', 'C', 'G', 'A', 'A', 'A', 'G', 'C', 'A', 'C', 'C',
           'A', 'C', 'C', 'T', 'G', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'A',
           'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A', 'G',
           'A', 'G', 'G', 'A', 'T', 'C', 'C', 'G', 'T', 'G', 'C', 'A', 'G',
           'A', 'C', 'A', 'T', 'T', 'G', 'T', 'G', 'G', 'A', 'G', 'A', 'A',
           'C', 'C', 'A', 'G', 'G', 'T', 'C', 'A', 'T', 'G', 'G', 'A', 'C',
           'A', 'C', 'C', 'C', 'G', 'C', 'A', 'T', 'G', 'C', 'A', 'G', 'C',
           'T', '-', 'C', 'A', 'T', 'C', 'A', 'T', 'G', 'C', 'T', 'C', 'T',
           'G', 'T', 'T', 'A', 'C', 'A', 'A', 'C', 'C', 'C', 'T', 'G', 'A',
           'C', 'T', 'T', 'T', 'G', 'A', 'G', 'A', 'A', 'G', 'C', 'A', 'G',
           'A', 'A', 'G', 'C', 'C', 'A', 'G', 'A', 'G', 'T', 'T', 'C', 'T',
           'T', 'G', 'A', 'A', 'G', 'A', 'C', 'C', 'A', 'T', 'C', 'C', 'C',
           'T', 'G', 'A', 'G', 'A', 'A', 'A', 'A', 'T', 'G', 'A', 'A', 'G',
           'C', 'T', 'C', 'T', '-', '-', '-', '-', '-', 'A', 'C', 'T', 'C',
           'T', 'G', '-', 'A', 'G', 'T', 'T', 'C', 'C', 'T', 'G', 'G', 'G',
           'C', 'A', 'A', '-', '-', 'G', 'A', 'G', 'G', 'C', 'C', 'A', 'T',
           'G', 'G', 'T', 'T', 'T', '-', '-', '-', '-', 'G', 'C', 'A', 'G',
           'G', 'G', 'G', 'A', 'C', 'A', 'A', 'G', 'G', 'T', 'C', 'A', 'C',
           'C', 'T', 'A', 'T', 'G', 'T', 'G', 'G', 'A', 'T', 'T', 'T', 'C',
           '-', '-', 'C', 'T', 'T', 'G', 'C', 'T', 'T', 'A', 'T', 'G', 'A',
           'C', 'A', 'T', 'T', 'C', 'T', 'T', 'G', 'A', 'C', 'C', 'A', 'G',
           'T', 'A', 'C', 'C', 'G', 'T', 'A', 'T', 'G', 'T', 'T', 'T', 'G',
           'A', 'G', 'C', 'C', 'C', 'A', 'A', 'G', 'T', 'G', 'C', 'C', 'T',
           'G', 'G', 'A', 'C', 'G', 'C', 'C', 'T', 'T', 'C', 'C', 'C', 'A',
           'A', 'A', 'C', 'C', 'T', 'G', 'A', 'G', 'G', 'G', 'A', 'C', 'T',
           'T', 'C', 'C', 'T', 'G', 'G', 'C', 'C', 'C', 'G', 'C', 'T', 'T',
           'C', 'G', 'A', 'G', 'G', 'G', 'C', 'C', 'T', 'C', 'A', 'A', 'G',
           'A', 'A', 'G', 'A', 'T', 'C', 'T', 'C', 'T', 'G', 'C', 'C', 'T',
           'A', 'C', 'A', 'T', 'G']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (413 aligned letters; 246 identities; 167 mismatches; 21 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 413:
        identities = 246,
        mismatches = 167.
    gaps = 21:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 21:
            internal_insertions = 6:
                open_internal_insertions = 3,
                extend_internal_insertions = 3;
            internal_deletions = 15:
                open_internal_deletions = 6,
                extend_internal_deletions = 9;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 6)
        self.assertEqual(counts.internal_deletions, 15)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 21)
        self.assertEqual(counts.insertions, 6)
        self.assertEqual(counts.deletions, 15)
        self.assertEqual(counts.gaps, 21)
        self.assertEqual(counts.aligned, 413)
        self.assertEqual(counts.identities, 246)
        self.assertEqual(counts.mismatches, 167)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 66.93)
        self.assertEqual(alignment.annotations["gap opens"], 8)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 127)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 127)
        self.assertEqual(alignment.shape, (2, 127 + 8))
        self.assertEqual(alignment.sequences[0].id, "RABGSTB")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 42)
        self.assertAlmostEqual(alignment.annotations["evalue"], 2.1e-07, places=8)
        self.assertAlmostEqual(alignment.annotations["bit score"], 45.6)
        self.assertEqual(
            str(alignment),
            """\
RABGSTB         156 ??????????????????????????????????--????????????????????????
                  0 |||||||||||||||--|||||||||||||||||--|||||||||||-||||||||||||
pGT875          158 ???????????????--??????????????????????????????-????????????

RABGSTB         214 ??????????????????????????????????????????????????????????-?
                 60 ||||||||||||||||||||||||||||||||||||||||||||||-|||||||||||-|
pGT875          215 ??????????????????????????????????????????????-?????????????

RABGSTB         273 ??????-???????? 287
                120 ||||||-|||||||| 135
pGT875          274 ??????????????? 289
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[156, 171, 173, 190, 190, 201, 202,
                           260, 261, 272, 272, 279, 279, 287],
                          [158, 173, 173, 190, 192, 203, 203,
                           261, 261, 272, 273, 280, 281, 289]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 287)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "GGGTATTGATGTTCCAGCAAGTGCCCATGGTTGA--GATTGATGGGATGAAGCTGGTGCAGACCAGAGCCATTTTCAACTACATTGCAGACAAGCACAACCTGTATGGGAAAGACATA-AAGGAGA-GAGCCCTG",
        )
        self.assertEqual(
            alignment[1],
            "GGGCCTGGACTTTCC--CAATCTGCCTTACTTGATCGATGGATCACA-CAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGAT-GGAGAGACAGAGGAGGAGAGGATCCGTG",
        )
        # pGT875   OCDHPR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'G', 'G', 'T', 'A', 'T', 'T', 'G', 'A', 'T', 'G', 'T', 'T',
           'C', 'C', 'A', 'G', 'C', 'A', 'A', 'G', 'T', 'G', 'C', 'C', 'C',
           'A', 'T', 'G', 'G', 'T', 'T', 'G', 'A', '-', '-', 'G', 'A', 'T',
           'T', 'G', 'A', 'T', 'G', 'G', 'G', 'A', 'T', 'G', 'A', 'A', 'G',
           'C', 'T', 'G', 'G', 'T', 'G', 'C', 'A', 'G', 'A', 'C', 'C', 'A',
           'G', 'A', 'G', 'C', 'C', 'A', 'T', 'T', 'T', 'T', 'C', 'A', 'A',
           'C', 'T', 'A', 'C', 'A', 'T', 'T', 'G', 'C', 'A', 'G', 'A', 'C',
           'A', 'A', 'G', 'C', 'A', 'C', 'A', 'A', 'C', 'C', 'T', 'G', 'T',
           'A', 'T', 'G', 'G', 'G', 'A', 'A', 'A', 'G', 'A', 'C', 'A', 'T',
           'A', '-', 'A', 'A', 'G', 'G', 'A', 'G', 'A', '-', 'G', 'A', 'G',
           'C', 'C', 'C', 'T', 'G'],
          ['G', 'G', 'G', 'C', 'C', 'T', 'G', 'G', 'A', 'C', 'T', 'T', 'T',
           'C', 'C', '-', '-', 'C', 'A', 'A', 'T', 'C', 'T', 'G', 'C', 'C',
           'T', 'T', 'A', 'C', 'T', 'T', 'G', 'A', 'T', 'C', 'G', 'A', 'T',
           'G', 'G', 'A', 'T', 'C', 'A', 'C', 'A', '-', 'C', 'A', 'A', 'G',
           'A', 'T', 'C', 'A', 'C', 'C', 'C', 'A', 'G', 'A', 'G', 'C', 'A',
           'A', 'T', 'G', 'C', 'C', 'A', 'T', 'C', 'C', 'T', 'G', 'C', 'G',
           'C', 'T', 'A', 'C', 'C', 'T', 'T', 'G', 'C', 'C', 'C', 'G', 'A',
           'A', 'A', 'G', 'C', 'A', 'C', 'C', 'A', 'C', 'C', 'T', 'G', 'G',
           'A', 'T', '-', 'G', 'G', 'A', 'G', 'A', 'G', 'A', 'C', 'A', 'G',
           'A', 'G', 'G', 'A', 'G', 'G', 'A', 'G', 'A', 'G', 'G', 'A', 'T',
           'C', 'C', 'G', 'T', 'G']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (127 aligned letters; 85 identities; 42 mismatches; 8 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 127:
        identities = 85,
        mismatches = 42.
    gaps = 8:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 8:
            internal_insertions = 4:
                open_internal_insertions = 3,
                extend_internal_insertions = 1;
            internal_deletions = 4:
                open_internal_deletions = 3,
                extend_internal_deletions = 1;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 4)
        self.assertEqual(counts.internal_deletions, 4)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 8)
        self.assertEqual(counts.insertions, 4)
        self.assertEqual(counts.deletions, 4)
        self.assertEqual(counts.gaps, 8)
        self.assertEqual(counts.aligned, 127)
        self.assertEqual(counts.identities, 85)
        self.assertEqual(counts.mismatches, 42)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 91.30)
        self.assertEqual(alignment.annotations["gap opens"], 1)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 23)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 23)
        self.assertEqual(alignment.shape, (2, 23 + 1))
        self.assertEqual(alignment.sequences[0].id, "OCDHPR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.0092)
        self.assertAlmostEqual(alignment.annotations["bit score"], 30.1)
        self.assertEqual(
            str(alignment),
            """\
OCDHPR         2302 ?????????????????-?????? 2325
                  0 |||||||||||||||||-||||||   24
pGT875          265 ????????????????????????  289
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[2302, 2319, 2319, 2325],
                          [ 265,  282,  283,  289]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 2325)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "AGACAGAGGAGGAGAAG-TCTGTG")
        self.assertEqual(alignment[1], "AGACAGAGGAGGAGAGGATCCGTG")
        # pGT875   RABALP1A
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['A', 'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'A', 'G', '-', 'T', 'C', 'T', 'G', 'T', 'G'],
          ['A', 'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C', 'C', 'G', 'T', 'G']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (23 aligned letters; 21 identities; 2 mismatches; 1 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 23:
        identities = 21,
        mismatches = 2.
    gaps = 1:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 1:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 1)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 1)
        self.assertEqual(counts.aligned, 23)
        self.assertEqual(counts.identities, 21)
        self.assertEqual(counts.mismatches, 2)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 76.19)
        self.assertEqual(alignment.annotations["gap opens"], 4)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 42)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 42)
        self.assertEqual(alignment.shape, (2, 42 + 4))
        self.assertEqual(alignment.sequences[0].id, "RABALP1A")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 10)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.036)
        self.assertAlmostEqual(alignment.annotations["bit score"], 28.1)
        self.assertEqual(
            str(alignment),
            """\
RABALP1A       4973 ??????????????--???-?????????????????????????? 5016
                  0 ||||||||||||||--|||-||||||||||||-|||||||||||||   46
pGT875          240 ????????????????????????????????-?????????????  285
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[4973, 4987, 4987, 4990, 4990, 5002, 5003, 5016],
                          [ 240,  254,  256,  259,  260,  272,  272,  285]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 5016)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "GCTGGAGAGAGCCA--TGG-TGGAGGCTGCGATGGAGGAGAGGATC")
        self.assertEqual(alignment[1], "GCCCGAAAGCACCACCTGGATGGAGAGACAGA-GGAGGAGAGGATC")
        # pGT875   OCDHPR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'C', 'T', 'G', 'G', 'A', 'G', 'A', 'G', 'A', 'G', 'C', 'C',
           'A', '-', '-', 'T', 'G', 'G', '-', 'T', 'G', 'G', 'A', 'G', 'G',
           'C', 'T', 'G', 'C', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C'],
          ['G', 'C', 'C', 'C', 'G', 'A', 'A', 'A', 'G', 'C', 'A', 'C', 'C',
           'A', 'C', 'C', 'T', 'G', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'A',
           'G', 'A', 'C', 'A', 'G', 'A', '-', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (42 aligned letters; 32 identities; 10 mismatches; 4 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 42:
        identities = 32,
        mismatches = 10.
    gaps = 4:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 4:
            internal_insertions = 3:
                open_internal_insertions = 2,
                extend_internal_insertions = 1;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 3)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 4)
        self.assertEqual(counts.insertions, 3)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 4)
        self.assertEqual(counts.aligned, 42)
        self.assertEqual(counts.identities, 32)
        self.assertEqual(counts.mismatches, 10)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 12)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 12)
        self.assertEqual(alignment.shape, (2, 12 + 0))
        self.assertEqual(alignment.sequences[0].id, "OCDHPR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.071)
        self.assertAlmostEqual(alignment.annotations["bit score"], 27.2)
        self.assertEqual(
            str(alignment),
            """\
OCDHPR         1499 ???????????? 1511
                  0 ||||||||||||   12
pGT875          316 ????????????  304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1499, 1511], [316, 304]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1511)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCATGACCTGGT")
        self.assertEqual(alignment[1], "CCATGACCTGGT")
        # pGT875   RABALP1A
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T'],
          ['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (12 aligned letters; 12 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 12:
        identities = 12,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 12)
        self.assertEqual(counts.identities, 12)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 12)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 12)
        self.assertEqual(alignment.shape, (2, 12 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABALP1A")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.071)
        self.assertAlmostEqual(alignment.annotations["bit score"], 27.2)
        self.assertEqual(
            str(alignment),
            """\
RABALP1A       1499 ???????????? 1511
                  0 ||||||||||||   12
pGT875          316 ????????????  304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1499, 1511], [316, 304]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1511)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCATGACCTGGT")
        self.assertEqual(alignment[1], "CCATGACCTGGT")
        # pGT875   RABGSTB
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T'],
          ['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (12 aligned letters; 12 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 12:
        identities = 12,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 12)
        self.assertEqual(counts.identities, 12)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 87.50)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 16)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 16)
        self.assertEqual(alignment.shape, (2, 16 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGSTB")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.14)
        self.assertAlmostEqual(alignment.annotations["bit score"], 26.2)
        self.assertEqual(
            str(alignment),
            """\
RABGSTB         490 ???????????????? 506
                  0 ||||||||||||||||  16
pGT875          160 ???????????????? 144
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[490, 506], [160, 144]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 506)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCTGGTTGAACTTCTC")
        self.assertEqual(alignment[1], "CCAGCTTGAACTTCTC")
        # pGT875   RABGLTR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'T', 'G', 'G', 'T', 'T', 'G', 'A', 'A', 'C', 'T', 'T',
           'C', 'T', 'C'],
          ['C', 'C', 'A', 'G', 'C', 'T', 'T', 'G', 'A', 'A', 'C', 'T', 'T',
           'C', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (16 aligned letters; 14 identities; 2 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 16:
        identities = 14,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 16)
        self.assertEqual(counts.identities, 14)
        self.assertEqual(counts.mismatches, 2)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 53.57)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 84)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 84)
        self.assertEqual(alignment.shape, (2, 84 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGLTR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 39)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.28)
        self.assertAlmostEqual(alignment.annotations["bit score"], 25.2)
        self.assertEqual(
            str(alignment),
            """\
RABGLTR        1116 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          242 ????????????????????????????????????????????????????????????

RABGLTR        1176 ???????????????????????? 1200
                 60 ||||||||||||||||||||||||   84
pGT875          182 ????????????????????????  158
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1116, 1200], [242, 158]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1200)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "GCATGGCTGGGTGGGGCAGGATTAGTGTGGGGGGAGTTGGGTGCTCAGGCAGGGCTATGAGGGATCTTGTTCATTTCCGGGCCC",
        )
        self.assertEqual(
            alignment[1],
            "GCAAGGTAGCGCAGGATGGCATTGCTCTGGGTGATCTTGTGTGATCCATCGATCAAGTAAGGCAGATTGGGAAAGTCCAGGCCC",
        )
        # pGT875   pGT875
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'C', 'A', 'T', 'G', 'G', 'C', 'T', 'G', 'G', 'G', 'T', 'G',
           'G', 'G', 'G', 'C', 'A', 'G', 'G', 'A', 'T', 'T', 'A', 'G', 'T',
           'G', 'T', 'G', 'G', 'G', 'G', 'G', 'G', 'A', 'G', 'T', 'T', 'G',
           'G', 'G', 'T', 'G', 'C', 'T', 'C', 'A', 'G', 'G', 'C', 'A', 'G',
           'G', 'G', 'C', 'T', 'A', 'T', 'G', 'A', 'G', 'G', 'G', 'A', 'T',
           'C', 'T', 'T', 'G', 'T', 'T', 'C', 'A', 'T', 'T', 'T', 'C', 'C',
           'G', 'G', 'G', 'C', 'C', 'C'],
          ['G', 'C', 'A', 'A', 'G', 'G', 'T', 'A', 'G', 'C', 'G', 'C', 'A',
           'G', 'G', 'A', 'T', 'G', 'G', 'C', 'A', 'T', 'T', 'G', 'C', 'T',
           'C', 'T', 'G', 'G', 'G', 'T', 'G', 'A', 'T', 'C', 'T', 'T', 'G',
           'T', 'G', 'T', 'G', 'A', 'T', 'C', 'C', 'A', 'T', 'C', 'G', 'A',
           'T', 'C', 'A', 'A', 'G', 'T', 'A', 'A', 'G', 'G', 'C', 'A', 'G',
           'A', 'T', 'T', 'G', 'G', 'G', 'A', 'A', 'A', 'G', 'T', 'C', 'C',
           'A', 'G', 'G', 'C', 'C', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (84 aligned letters; 45 identities; 39 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 84:
        identities = 45,
        mismatches = 39.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 84)
        self.assertEqual(counts.identities, 45)
        self.assertEqual(counts.mismatches, 39)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 10)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 10)
        self.assertEqual(alignment.shape, (2, 10 + 0))
        self.assertEqual(alignment.sequences[0].id, "pGT875")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.28)
        self.assertAlmostEqual(alignment.annotations["bit score"], 25.2)
        self.assertEqual(
            str(alignment),
            """\
pGT875          792 ?????????? 802
                  0 ||||||||||  10
pGT875          310 ?????????? 300
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[792, 802], [310, 300]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 802)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCTGGTTCTC")
        self.assertEqual(alignment[1], "CCTGGTTCTC")
        # pGT875   BTGST
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'T', 'G', 'G', 'T', 'T', 'C', 'T', 'C'],
          ['C', 'C', 'T', 'G', 'G', 'T', 'T', 'C', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (10 aligned letters; 10 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 10:
        identities = 10,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 10)
        self.assertEqual(counts.identities, 10)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 59.15)
        self.assertEqual(alignment.annotations["gap opens"], 3)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 71)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 71)
        self.assertEqual(alignment.shape, (2, 71 + 3))
        self.assertEqual(alignment.sequences[0].id, "BTGST")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 29)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.56)
        self.assertAlmostEqual(alignment.annotations["bit score"], 24.2)
        self.assertEqual(
            str(alignment),
            """\
BTGST           280 ????????????????????????-????????--?????????????????????????
                  0 ||||||||||||||||||||||||-||||||||--|||||||||||||||||||||||||
pGT875          378 ????????????????????????????????????????????????????????????

BTGST           337 ?????????????? 351
                 60 ||||||||||||||  74
pGT875          318 ?????????????? 304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[280, 304, 304, 312, 312, 351],
                          [378, 354, 353, 345, 343, 304]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 351)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "CTGCGGCACCTGGGCCGCACCCTC-GGGCTGTA--TGGGAAGGACCAGCAGGAGGCGGCCCTGGTGGACATGGT",
        )
        self.assertEqual(
            alignment[1],
            "CTCTGGCTTCTGCTTCTCAAAGTCAGGGTTGTAACAGAGCATGATGAGCTGCATGCGGGTGTCCATGACCTGGT",
        )
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'T', 'G', 'C', 'G', 'G', 'C', 'A', 'C', 'C', 'T', 'G', 'G',
           'G', 'C', 'C', 'G', 'C', 'A', 'C', 'C', 'C', 'T', 'C', '-', 'G',
           'G', 'G', 'C', 'T', 'G', 'T', 'A', '-', '-', 'T', 'G', 'G', 'G',
           'A', 'A', 'G', 'G', 'A', 'C', 'C', 'A', 'G', 'C', 'A', 'G', 'G',
           'A', 'G', 'G', 'C', 'G', 'G', 'C', 'C', 'C', 'T', 'G', 'G', 'T',
           'G', 'G', 'A', 'C', 'A', 'T', 'G', 'G', 'T'],
          ['C', 'T', 'C', 'T', 'G', 'G', 'C', 'T', 'T', 'C', 'T', 'G', 'C',
           'T', 'T', 'C', 'T', 'C', 'A', 'A', 'A', 'G', 'T', 'C', 'A', 'G',
           'G', 'G', 'T', 'T', 'G', 'T', 'A', 'A', 'C', 'A', 'G', 'A', 'G',
           'C', 'A', 'T', 'G', 'A', 'T', 'G', 'A', 'G', 'C', 'T', 'G', 'C',
           'A', 'T', 'G', 'C', 'G', 'G', 'G', 'T', 'G', 'T', 'C', 'C', 'A',
           'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (71 aligned letters; 42 identities; 29 mismatches; 3 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 71:
        identities = 42,
        mismatches = 29.
    gaps = 3:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 3:
            internal_insertions = 3:
                open_internal_insertions = 2,
                extend_internal_insertions = 1;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 3)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 3)
        self.assertEqual(counts.insertions, 3)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 3)
        self.assertEqual(counts.aligned, 71)
        self.assertEqual(counts.identities, 42)
        self.assertEqual(counts.mismatches, 29)
        with self.assertRaises(StopIteration):
            next(alignments)

    def test_m8CC(self):
        # Alignment file obtained by running
        # fasta36 -m 8CC seq/mgstm1.nt seq/gst.nlib
        # in the fasta36 source distribution
        path = "Fasta/nucleotide_m8CC.txt"
        alignments = Align.parse(path, "tabular")
        self.assertEqual(
            alignments.metadata["Command line"],
            "fasta36 -m 8CC seq/mgstm1.nt seq/gst.nlib",
        )
        self.assertEqual(alignments.metadata["Program"], "FASTA")
        self.assertEqual(alignments.metadata["Version"], "36.3.8h May, 2020")
        self.assertEqual(alignments.metadata["Database"], "seq/gst.nlib")
        # pGT875   pGT875
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 657)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 657)
        self.assertEqual(alignment.shape, (2, 657 + 0))
        self.assertEqual(alignment.sequences[0].id, "pGT875")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 4.6e-191, places=192)
        self.assertAlmostEqual(alignment.annotations["bit score"], 655.6)
        self.assertEqual(
            str(alignment),
            """\
pGT875           37 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875            0 ????????????????????????????????????????????????????????????

pGT875           97 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875           60 ????????????????????????????????????????????????????????????

pGT875          157 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          120 ????????????????????????????????????????????????????????????

pGT875          217 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          180 ????????????????????????????????????????????????????????????

pGT875          277 ????????????????????????????????????????????????????????????
                240 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          240 ????????????????????????????????????????????????????????????

pGT875          337 ????????????????????????????????????????????????????????????
                300 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          300 ????????????????????????????????????????????????????????????

pGT875          397 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          360 ????????????????????????????????????????????????????????????

pGT875          457 ????????????????????????????????????????????????????????????
                420 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          420 ????????????????????????????????????????????????????????????

pGT875          517 ????????????????????????????????????????????????????????????
                480 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          480 ????????????????????????????????????????????????????????????

pGT875          577 ????????????????????????????????????????????????????????????
                540 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          540 ????????????????????????????????????????????????????????????

pGT875          637 ????????????????????????????????????????????????????????? 694
                600 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 657
pGT875          600 ????????????????????????????????????????????????????????? 657
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[37, 694], [0, 657]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 694)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGAGTAACAAGTAG",
        )
        self.assertEqual(
            alignment[1],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGAGTAACAAGTAG",
        )
        # pGT875   RABGLTR
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (657 aligned letters; 657 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 657:
        identities = 657,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 657)
        self.assertEqual(counts.identities, 657)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 79.10)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 646)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 646)
        self.assertEqual(alignment.shape, (2, 646 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGLTR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 135)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.6e-116, places=117)
        self.assertAlmostEqual(alignment.annotations["bit score"], 408.0)
        self.assertEqual(
            str(alignment),
            """\
RABGLTR          33 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875            0 ????????????????????????????????????????????????????????????

RABGLTR          93 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875           60 ????????????????????????????????????????????????????????????

RABGLTR         153 ????????????????????????????????????????????????????????????
                120 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          120 ????????????????????????????????????????????????????????????

RABGLTR         213 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          180 ????????????????????????????????????????????????????????????

RABGLTR         273 ????????????????????????????????????????????????????????????
                240 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          240 ????????????????????????????????????????????????????????????

RABGLTR         333 ????????????????????????????????????????????????????????????
                300 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          300 ????????????????????????????????????????????????????????????

RABGLTR         393 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          360 ????????????????????????????????????????????????????????????

RABGLTR         453 ????????????????????????????????????????????????????????????
                420 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          420 ????????????????????????????????????????????????????????????

RABGLTR         513 ????????????????????????????????????????????????????????????
                480 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          480 ????????????????????????????????????????????????????????????

RABGLTR         573 ????????????????????????????????????????????????????????????
                540 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          540 ????????????????????????????????????????????????????????????

RABGLTR         633 ?????????????????????????????????????????????? 679
                600 |||||||||||||||||||||||||||||||||||||||||||||| 646
pGT875          600 ?????????????????????????????????????????????? 646
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[33, 679], [0, 646]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 679)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "ATGCCCATGACGCTGGGTTACTGGGACGTCCGTGGGCTGGCTCTGCCAATCCGCATGCTCCTGGAATACACGGACACCAGCTATGAGGAAAAGAAATACACCATGGGGGATGCTCCCAACTATGACCAAAGCAAGTGGCTGAGTGAGAAGTTCACCCTGGGCCTGGACTTTCCCAATCTGCCCTACCTAATTGATGGGACTCACAAGCTCACGCAGAGCAACGCCATCCTGCGCTACCTGGCCCGCAAGCACGGCCTGTGTGGGGAGACGGAAGAGGAGAGGATTCGCGTGGACATTCTGGAGAATCAGCTGATGGACAACCGCTTCCAACTTGTAAACGTCTGCTACAGTCCCGACTTTGAGAAGCTCAAGCCCGAGTACCTGAAGGGGCTCCCTGAGAAGCTGCAGCTGTACTCGCAGTTCCTGGGAAGCCTCCCCTGGTTCGCAGGGGACAAGATCACCTTCGCCGATTTCCTTGTCTACGACGTTCTTGACCAGAACCGGATATTTGTGCCTGGGTGCCTGGACGCGTTCCCAAACCTGAAGGACTTTCATGTCCGCTTTGAGGGCCTGCCGAAGATCTCTGCCTACATGAAGTCCAGCCGCTTTATCCGAGTCCCTGTGTTTTTAAAGAAGGCCACGTGGA",
        )
        self.assertEqual(
            alignment[1],
            "ATGCCTATGATACTGGGATACTGGAACGTCCGCGGACTGACACACCCGATCCGCATGCTCCTGGAATACACAGACTCAAGCTATGATGAGAAGAGATACACCATGGGTGACGCTCCCGACTTTGACAGAAGCCAGTGGCTGAATGAGAAGTTCAAGCTGGGCCTGGACTTTCCCAATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCTCATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCTACTCTGAGTTCCTGGGCAAGAGGCCATGGTTTGCAGGGGACAAGGTCACCTATGTGGATTTCCTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATGAAGAGTAGCCGCTACATCGCAACACCTATATTTTCAAAGATGGCCCACTGGA",
        )
        # pGT875   BTGST
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (646 aligned letters; 511 identities; 135 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 646:
        identities = 511,
        mismatches = 135.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 646)
        self.assertEqual(counts.identities, 511)
        self.assertEqual(counts.mismatches, 135)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 59.56)
        self.assertEqual(alignment.annotations["gap opens"], 21)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 413)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 413)
        self.assertEqual(alignment.shape, (2, 413 + 21))
        self.assertEqual(alignment.sequences[0].id, "BTGST")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 167)
        self.assertAlmostEqual(alignment.annotations["evalue"], 1.9e-07, places=8)
        self.assertAlmostEqual(alignment.annotations["bit score"], 45.7)
        self.assertEqual(
            str(alignment),
            """\
BTGST           227 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          175 ????????????????????????????????????????????????????????????

BTGST           287 ????????????????????????????????????????????????????????????
                 60 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          235 ????????????????????????????????????????????????????????????

BTGST           347 ?????????????????????????????-?????????????????????????---??
                120 |||||||||||||||||||||||||||||-|||||||-|||||||||||||||||---||
pGT875          295 ?????????????????????????????????????-??????????????????????

BTGST           403 ????????????????????????????????????????????????????????????
                180 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||--
pGT875          354 ??????????????????????????????????????????????????????????--

BTGST           463 ????????????????????????????????????????????????????????????
                240 ---||||||-|||||||||||||--|||||||||||||----||||||||||||||||||
pGT875          412 ---??????-?????????????--?????????????----??????????????????

BTGST           523 ????????????????????--??????????????????????????????????????
                300 ||||||||||||--||||||--||||||||||||||||||||||||||||||||||||||
pGT875          462 ????????????--??????????????????????????????????????????????

BTGST           581 ????????????????????????????????????????????????????????????
                360 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          520 ????????????????????????????????????????????????????????????

BTGST           641 ?????????????? 655
                420 |||||||||||||| 434
pGT875          580 ?????????????? 594
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[227, 376, 376, 383, 384, 401, 401, 461, 466, 472,
                           473, 486, 488, 501, 505, 535, 537, 543, 543, 655],
                          [175, 324, 325, 332, 332, 349, 352, 412, 412, 418,
                           418, 431, 431, 444, 444, 474, 474, 480, 482, 594]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 655)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "AGCTCCCCAAGTTCCAGGACGGAGACCTCACGCTGTACCAGTCCAATGCCATCCTGCGGCACCTGGGCCGCACCCTCGGGCTGTATGGGAAGGACCAGCAGGAGGCGGCCCTGGTGGACATGGTGAATGACGGTGTAGAGGACCTTCGC-TGCAAATACGTCTCCCTCATTTACA---CCAACTACGAGGCGGGCAAGGAGGACTATGTGAAGGCGCTGCCCCAGCACCTGAAGCCTTTCGAGACCCTGCTGTCCCAGAACAAGGGTGGCCAGGCCTTCATCGTGGGCGACCAGATCTCCTTTGCGGACTACAACCTGCT--GGACCTGCTTCGGATTCACCAGGTCCTGGCCCCCAGCTGTCTGGACTCCTTCCCCCTGCTCTCAGCCTACGTGGCCCGTCTCAACTCCCGGCCCAAGCTCAAGGCCTTCCTG",
        )
        self.assertEqual(
            alignment[1],
            "ATCTGCCTTACTTGATCGATGGATCACACAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGATGGAGAGACAGAGGAGGAGAGGATCCGTGCAGACATTGTGGAGAACCAGGTCATGGACACCCGCATGCAGCT-CATCATGCTCTGTTACAACCCTGACTTTGAGAAGCAGAAGCCAGAGTTCTTGAAGACCATCCCTGAGAAAATGAAGCTCT-----ACTCTG-AGTTCCTGGGCAA--GAGGCCATGGTTT----GCAGGGGACAAGGTCACCTATGTGGATTTC--CTTGCTTATGACATTCTTGACCAGTACCGTATGTTTGAGCCCAAGTGCCTGGACGCCTTCCCAAACCTGAGGGACTTCCTGGCCCGCTTCGAGGGCCTCAAGAAGATCTCTGCCTACATG",
        )
        # pGT875   RABGSTB
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['A', 'G', 'C', 'T', 'C', 'C', 'C', 'C', 'A', 'A', 'G', 'T', 'T',
           'C', 'C', 'A', 'G', 'G', 'A', 'C', 'G', 'G', 'A', 'G', 'A', 'C',
           'C', 'T', 'C', 'A', 'C', 'G', 'C', 'T', 'G', 'T', 'A', 'C', 'C',
           'A', 'G', 'T', 'C', 'C', 'A', 'A', 'T', 'G', 'C', 'C', 'A', 'T',
           'C', 'C', 'T', 'G', 'C', 'G', 'G', 'C', 'A', 'C', 'C', 'T', 'G',
           'G', 'G', 'C', 'C', 'G', 'C', 'A', 'C', 'C', 'C', 'T', 'C', 'G',
           'G', 'G', 'C', 'T', 'G', 'T', 'A', 'T', 'G', 'G', 'G', 'A', 'A',
           'G', 'G', 'A', 'C', 'C', 'A', 'G', 'C', 'A', 'G', 'G', 'A', 'G',
           'G', 'C', 'G', 'G', 'C', 'C', 'C', 'T', 'G', 'G', 'T', 'G', 'G',
           'A', 'C', 'A', 'T', 'G', 'G', 'T', 'G', 'A', 'A', 'T', 'G', 'A',
           'C', 'G', 'G', 'T', 'G', 'T', 'A', 'G', 'A', 'G', 'G', 'A', 'C',
           'C', 'T', 'T', 'C', 'G', 'C', '-', 'T', 'G', 'C', 'A', 'A', 'A',
           'T', 'A', 'C', 'G', 'T', 'C', 'T', 'C', 'C', 'C', 'T', 'C', 'A',
           'T', 'T', 'T', 'A', 'C', 'A', '-', '-', '-', 'C', 'C', 'A', 'A',
           'C', 'T', 'A', 'C', 'G', 'A', 'G', 'G', 'C', 'G', 'G', 'G', 'C',
           'A', 'A', 'G', 'G', 'A', 'G', 'G', 'A', 'C', 'T', 'A', 'T', 'G',
           'T', 'G', 'A', 'A', 'G', 'G', 'C', 'G', 'C', 'T', 'G', 'C', 'C',
           'C', 'C', 'A', 'G', 'C', 'A', 'C', 'C', 'T', 'G', 'A', 'A', 'G',
           'C', 'C', 'T', 'T', 'T', 'C', 'G', 'A', 'G', 'A', 'C', 'C', 'C',
           'T', 'G', 'C', 'T', 'G', 'T', 'C', 'C', 'C', 'A', 'G', 'A', 'A',
           'C', 'A', 'A', 'G', 'G', 'G', 'T', 'G', 'G', 'C', 'C', 'A', 'G',
           'G', 'C', 'C', 'T', 'T', 'C', 'A', 'T', 'C', 'G', 'T', 'G', 'G',
           'G', 'C', 'G', 'A', 'C', 'C', 'A', 'G', 'A', 'T', 'C', 'T', 'C',
           'C', 'T', 'T', 'T', 'G', 'C', 'G', 'G', 'A', 'C', 'T', 'A', 'C',
           'A', 'A', 'C', 'C', 'T', 'G', 'C', 'T', '-', '-', 'G', 'G', 'A',
           'C', 'C', 'T', 'G', 'C', 'T', 'T', 'C', 'G', 'G', 'A', 'T', 'T',
           'C', 'A', 'C', 'C', 'A', 'G', 'G', 'T', 'C', 'C', 'T', 'G', 'G',
           'C', 'C', 'C', 'C', 'C', 'A', 'G', 'C', 'T', 'G', 'T', 'C', 'T',
           'G', 'G', 'A', 'C', 'T', 'C', 'C', 'T', 'T', 'C', 'C', 'C', 'C',
           'C', 'T', 'G', 'C', 'T', 'C', 'T', 'C', 'A', 'G', 'C', 'C', 'T',
           'A', 'C', 'G', 'T', 'G', 'G', 'C', 'C', 'C', 'G', 'T', 'C', 'T',
           'C', 'A', 'A', 'C', 'T', 'C', 'C', 'C', 'G', 'G', 'C', 'C', 'C',
           'A', 'A', 'G', 'C', 'T', 'C', 'A', 'A', 'G', 'G', 'C', 'C', 'T',
           'T', 'C', 'C', 'T', 'G'],
          ['A', 'T', 'C', 'T', 'G', 'C', 'C', 'T', 'T', 'A', 'C', 'T', 'T',
           'G', 'A', 'T', 'C', 'G', 'A', 'T', 'G', 'G', 'A', 'T', 'C', 'A',
           'C', 'A', 'C', 'A', 'A', 'G', 'A', 'T', 'C', 'A', 'C', 'C', 'C',
           'A', 'G', 'A', 'G', 'C', 'A', 'A', 'T', 'G', 'C', 'C', 'A', 'T',
           'C', 'C', 'T', 'G', 'C', 'G', 'C', 'T', 'A', 'C', 'C', 'T', 'T',
           'G', 'C', 'C', 'C', 'G', 'A', 'A', 'A', 'G', 'C', 'A', 'C', 'C',
           'A', 'C', 'C', 'T', 'G', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'A',
           'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A', 'G',
           'A', 'G', 'G', 'A', 'T', 'C', 'C', 'G', 'T', 'G', 'C', 'A', 'G',
           'A', 'C', 'A', 'T', 'T', 'G', 'T', 'G', 'G', 'A', 'G', 'A', 'A',
           'C', 'C', 'A', 'G', 'G', 'T', 'C', 'A', 'T', 'G', 'G', 'A', 'C',
           'A', 'C', 'C', 'C', 'G', 'C', 'A', 'T', 'G', 'C', 'A', 'G', 'C',
           'T', '-', 'C', 'A', 'T', 'C', 'A', 'T', 'G', 'C', 'T', 'C', 'T',
           'G', 'T', 'T', 'A', 'C', 'A', 'A', 'C', 'C', 'C', 'T', 'G', 'A',
           'C', 'T', 'T', 'T', 'G', 'A', 'G', 'A', 'A', 'G', 'C', 'A', 'G',
           'A', 'A', 'G', 'C', 'C', 'A', 'G', 'A', 'G', 'T', 'T', 'C', 'T',
           'T', 'G', 'A', 'A', 'G', 'A', 'C', 'C', 'A', 'T', 'C', 'C', 'C',
           'T', 'G', 'A', 'G', 'A', 'A', 'A', 'A', 'T', 'G', 'A', 'A', 'G',
           'C', 'T', 'C', 'T', '-', '-', '-', '-', '-', 'A', 'C', 'T', 'C',
           'T', 'G', '-', 'A', 'G', 'T', 'T', 'C', 'C', 'T', 'G', 'G', 'G',
           'C', 'A', 'A', '-', '-', 'G', 'A', 'G', 'G', 'C', 'C', 'A', 'T',
           'G', 'G', 'T', 'T', 'T', '-', '-', '-', '-', 'G', 'C', 'A', 'G',
           'G', 'G', 'G', 'A', 'C', 'A', 'A', 'G', 'G', 'T', 'C', 'A', 'C',
           'C', 'T', 'A', 'T', 'G', 'T', 'G', 'G', 'A', 'T', 'T', 'T', 'C',
           '-', '-', 'C', 'T', 'T', 'G', 'C', 'T', 'T', 'A', 'T', 'G', 'A',
           'C', 'A', 'T', 'T', 'C', 'T', 'T', 'G', 'A', 'C', 'C', 'A', 'G',
           'T', 'A', 'C', 'C', 'G', 'T', 'A', 'T', 'G', 'T', 'T', 'T', 'G',
           'A', 'G', 'C', 'C', 'C', 'A', 'A', 'G', 'T', 'G', 'C', 'C', 'T',
           'G', 'G', 'A', 'C', 'G', 'C', 'C', 'T', 'T', 'C', 'C', 'C', 'A',
           'A', 'A', 'C', 'C', 'T', 'G', 'A', 'G', 'G', 'G', 'A', 'C', 'T',
           'T', 'C', 'C', 'T', 'G', 'G', 'C', 'C', 'C', 'G', 'C', 'T', 'T',
           'C', 'G', 'A', 'G', 'G', 'G', 'C', 'C', 'T', 'C', 'A', 'A', 'G',
           'A', 'A', 'G', 'A', 'T', 'C', 'T', 'C', 'T', 'G', 'C', 'C', 'T',
           'A', 'C', 'A', 'T', 'G']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (413 aligned letters; 246 identities; 167 mismatches; 21 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 413:
        identities = 246,
        mismatches = 167.
    gaps = 21:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 21:
            internal_insertions = 6:
                open_internal_insertions = 3,
                extend_internal_insertions = 3;
            internal_deletions = 15:
                open_internal_deletions = 6,
                extend_internal_deletions = 9;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 6)
        self.assertEqual(counts.internal_deletions, 15)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 21)
        self.assertEqual(counts.insertions, 6)
        self.assertEqual(counts.deletions, 15)
        self.assertEqual(counts.gaps, 21)
        self.assertEqual(counts.aligned, 413)
        self.assertEqual(counts.identities, 246)
        self.assertEqual(counts.mismatches, 167)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 66.93)
        self.assertEqual(alignment.annotations["gap opens"], 8)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 127)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 127)
        self.assertEqual(alignment.shape, (2, 127 + 8))
        self.assertEqual(alignment.sequences[0].id, "RABGSTB")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 42)
        self.assertAlmostEqual(alignment.annotations["evalue"], 3.2e-07, places=8)
        self.assertAlmostEqual(alignment.annotations["bit score"], 45.0)
        self.assertEqual(
            str(alignment),
            """\
RABGSTB         156 ??????????????????????????????????--????????????????????????
                  0 |||||||||||||||--|||||||||||||||||--|||||||||||-||||||||||||
pGT875          158 ???????????????--??????????????????????????????-????????????

RABGSTB         214 ??????????????????????????????????????????????????????????-?
                 60 ||||||||||||||||||||||||||||||||||||||||||||||-|||||||||||-|
pGT875          215 ??????????????????????????????????????????????-?????????????

RABGSTB         273 ??????-???????? 287
                120 ||||||-|||||||| 135
pGT875          274 ??????????????? 289
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[156, 171, 173, 190, 190, 201, 202,
                           260, 261, 272, 272, 279, 279, 287],
                          [158, 173, 173, 190, 192, 203, 203,
                           261, 261, 272, 273, 280, 281, 289]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 287)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "GGGTATTGATGTTCCAGCAAGTGCCCATGGTTGA--GATTGATGGGATGAAGCTGGTGCAGACCAGAGCCATTTTCAACTACATTGCAGACAAGCACAACCTGTATGGGAAAGACATA-AAGGAGA-GAGCCCTG",
        )
        self.assertEqual(
            alignment[1],
            "GGGCCTGGACTTTCC--CAATCTGCCTTACTTGATCGATGGATCACA-CAAGATCACCCAGAGCAATGCCATCCTGCGCTACCTTGCCCGAAAGCACCACCTGGAT-GGAGAGACAGAGGAGGAGAGGATCCGTG",
        )
        # pGT875   OCDHPR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'G', 'G', 'T', 'A', 'T', 'T', 'G', 'A', 'T', 'G', 'T', 'T',
           'C', 'C', 'A', 'G', 'C', 'A', 'A', 'G', 'T', 'G', 'C', 'C', 'C',
           'A', 'T', 'G', 'G', 'T', 'T', 'G', 'A', '-', '-', 'G', 'A', 'T',
           'T', 'G', 'A', 'T', 'G', 'G', 'G', 'A', 'T', 'G', 'A', 'A', 'G',
           'C', 'T', 'G', 'G', 'T', 'G', 'C', 'A', 'G', 'A', 'C', 'C', 'A',
           'G', 'A', 'G', 'C', 'C', 'A', 'T', 'T', 'T', 'T', 'C', 'A', 'A',
           'C', 'T', 'A', 'C', 'A', 'T', 'T', 'G', 'C', 'A', 'G', 'A', 'C',
           'A', 'A', 'G', 'C', 'A', 'C', 'A', 'A', 'C', 'C', 'T', 'G', 'T',
           'A', 'T', 'G', 'G', 'G', 'A', 'A', 'A', 'G', 'A', 'C', 'A', 'T',
           'A', '-', 'A', 'A', 'G', 'G', 'A', 'G', 'A', '-', 'G', 'A', 'G',
           'C', 'C', 'C', 'T', 'G'],
          ['G', 'G', 'G', 'C', 'C', 'T', 'G', 'G', 'A', 'C', 'T', 'T', 'T',
           'C', 'C', '-', '-', 'C', 'A', 'A', 'T', 'C', 'T', 'G', 'C', 'C',
           'T', 'T', 'A', 'C', 'T', 'T', 'G', 'A', 'T', 'C', 'G', 'A', 'T',
           'G', 'G', 'A', 'T', 'C', 'A', 'C', 'A', '-', 'C', 'A', 'A', 'G',
           'A', 'T', 'C', 'A', 'C', 'C', 'C', 'A', 'G', 'A', 'G', 'C', 'A',
           'A', 'T', 'G', 'C', 'C', 'A', 'T', 'C', 'C', 'T', 'G', 'C', 'G',
           'C', 'T', 'A', 'C', 'C', 'T', 'T', 'G', 'C', 'C', 'C', 'G', 'A',
           'A', 'A', 'G', 'C', 'A', 'C', 'C', 'A', 'C', 'C', 'T', 'G', 'G',
           'A', 'T', '-', 'G', 'G', 'A', 'G', 'A', 'G', 'A', 'C', 'A', 'G',
           'A', 'G', 'G', 'A', 'G', 'G', 'A', 'G', 'A', 'G', 'G', 'A', 'T',
           'C', 'C', 'G', 'T', 'G']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (127 aligned letters; 85 identities; 42 mismatches; 8 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 127:
        identities = 85,
        mismatches = 42.
    gaps = 8:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 8:
            internal_insertions = 4:
                open_internal_insertions = 3,
                extend_internal_insertions = 1;
            internal_deletions = 4:
                open_internal_deletions = 3,
                extend_internal_deletions = 1;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 4)
        self.assertEqual(counts.internal_deletions, 4)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 8)
        self.assertEqual(counts.insertions, 4)
        self.assertEqual(counts.deletions, 4)
        self.assertEqual(counts.gaps, 8)
        self.assertEqual(counts.aligned, 127)
        self.assertEqual(counts.identities, 85)
        self.assertEqual(counts.mismatches, 42)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 91.30)
        self.assertEqual(alignment.annotations["gap opens"], 1)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 23)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 23)
        self.assertEqual(alignment.shape, (2, 23 + 1))
        self.assertEqual(alignment.sequences[0].id, "OCDHPR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.012)
        self.assertAlmostEqual(alignment.annotations["bit score"], 29.7)
        self.assertEqual(
            str(alignment),
            """\
OCDHPR         2302 ?????????????????-?????? 2325
                  0 |||||||||||||||||-||||||   24
pGT875          265 ????????????????????????  289
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[2302, 2319, 2319, 2325],
                           [265,  282,  283,  289]]),
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 2325)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "AGACAGAGGAGGAGAAG-TCTGTG")
        self.assertEqual(alignment[1], "AGACAGAGGAGGAGAGGATCCGTG")
        # pGT875   RABALP1A
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['A', 'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'A', 'G', '-', 'T', 'C', 'T', 'G', 'T', 'G'],
          ['A', 'G', 'A', 'C', 'A', 'G', 'A', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C', 'C', 'G', 'T', 'G']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (23 aligned letters; 21 identities; 2 mismatches; 1 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 23:
        identities = 21,
        mismatches = 2.
    gaps = 1:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 1:
            internal_insertions = 1:
                open_internal_insertions = 1,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 1)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 1)
        self.assertEqual(counts.insertions, 1)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 1)
        self.assertEqual(counts.aligned, 23)
        self.assertEqual(counts.identities, 21)
        self.assertEqual(counts.mismatches, 2)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 76.19)
        self.assertEqual(alignment.annotations["gap opens"], 4)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 42)
        self.assertEqual(sum(end - start for start, end in aligned[1]), 42)
        self.assertEqual(alignment.shape, (2, 42 + 4))
        self.assertEqual(alignment.sequences[0].id, "RABALP1A")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 10)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.046)
        self.assertAlmostEqual(alignment.annotations["bit score"], 27.8)
        self.assertEqual(
            str(alignment),
            """\
RABALP1A       4973 ??????????????--???-?????????????????????????? 5016
                  0 ||||||||||||||--|||-||||||||||||-|||||||||||||   46
pGT875          240 ????????????????????????????????-?????????????  285
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[4973, 4987, 4987, 4990, 4990, 5002, 5003, 5016],
                          [ 240,  254,  256,  259,  260,  272,  272,  285]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 5016)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "GCTGGAGAGAGCCA--TGG-TGGAGGCTGCGATGGAGGAGAGGATC")
        self.assertEqual(alignment[1], "GCCCGAAAGCACCACCTGGATGGAGAGACAGA-GGAGGAGAGGATC")
        # pGT875   OCDHPR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'C', 'T', 'G', 'G', 'A', 'G', 'A', 'G', 'A', 'G', 'C', 'C',
           'A', '-', '-', 'T', 'G', 'G', '-', 'T', 'G', 'G', 'A', 'G', 'G',
           'C', 'T', 'G', 'C', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C'],
          ['G', 'C', 'C', 'C', 'G', 'A', 'A', 'A', 'G', 'C', 'A', 'C', 'C',
           'A', 'C', 'C', 'T', 'G', 'G', 'A', 'T', 'G', 'G', 'A', 'G', 'A',
           'G', 'A', 'C', 'A', 'G', 'A', '-', 'G', 'G', 'A', 'G', 'G', 'A',
           'G', 'A', 'G', 'G', 'A', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (42 aligned letters; 32 identities; 10 mismatches; 4 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 42:
        identities = 32,
        mismatches = 10.
    gaps = 4:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 4:
            internal_insertions = 3:
                open_internal_insertions = 2,
                extend_internal_insertions = 1;
            internal_deletions = 1:
                open_internal_deletions = 1,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 3)
        self.assertEqual(counts.internal_deletions, 1)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 4)
        self.assertEqual(counts.insertions, 3)
        self.assertEqual(counts.deletions, 1)
        self.assertEqual(counts.gaps, 4)
        self.assertEqual(counts.aligned, 42)
        self.assertEqual(counts.identities, 32)
        self.assertEqual(counts.mismatches, 10)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 12)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 12)
        self.assertEqual(alignment.shape, (2, 12 + 0))
        self.assertEqual(alignment.sequences[0].id, "OCDHPR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.09)
        self.assertAlmostEqual(alignment.annotations["bit score"], 26.8)
        self.assertEqual(
            str(alignment),
            """\
OCDHPR         1499 ???????????? 1511
                  0 ||||||||||||   12
pGT875          316 ????????????  304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1499, 1511], [316, 304]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1511)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCATGACCTGGT")
        self.assertEqual(alignment[1], "CCATGACCTGGT")
        # pGT875   RABALP1A
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T'],
          ['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (12 aligned letters; 12 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 12:
        identities = 12,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 12)
        self.assertEqual(counts.identities, 12)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 12)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 12)
        self.assertEqual(alignment.shape, (2, 12 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABALP1A")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.09)
        self.assertAlmostEqual(alignment.annotations["bit score"], 26.8)
        self.assertEqual(
            str(alignment),
            """\
RABALP1A       1499 ???????????? 1511
                  0 ||||||||||||   12
pGT875          316 ????????????  304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1499, 1511], [316, 304]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1511)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCATGACCTGGT")
        self.assertEqual(alignment[1], "CCATGACCTGGT")
        # pGT875   RABGSTB
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T'],
          ['C', 'C', 'A', 'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']],
         dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (12 aligned letters; 12 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 12:
        identities = 12,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 12)
        self.assertEqual(counts.identities, 12)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 87.50)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 16)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 16)
        self.assertEqual(alignment.shape, (2, 16 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGSTB")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 2)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.18)
        self.assertAlmostEqual(alignment.annotations["bit score"], 25.8)
        self.assertEqual(
            str(alignment),
            """\
RABGSTB         490 ???????????????? 506
                  0 ||||||||||||||||  16
pGT875          160 ???????????????? 144
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[490, 506], [160, 144]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 506)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCTGGTTGAACTTCTC")
        self.assertEqual(alignment[1], "CCAGCTTGAACTTCTC")
        # pGT875   RABGLTR
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'T', 'G', 'G', 'T', 'T', 'G', 'A', 'A', 'C', 'T', 'T',
           'C', 'T', 'C'],
          ['C', 'C', 'A', 'G', 'C', 'T', 'T', 'G', 'A', 'A', 'C', 'T', 'T',
           'C', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (16 aligned letters; 14 identities; 2 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 16:
        identities = 14,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 16)
        self.assertEqual(counts.identities, 14)
        self.assertEqual(counts.mismatches, 2)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 53.57)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 84)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 84)
        self.assertEqual(alignment.shape, (2, 84 + 0))
        self.assertEqual(alignment.sequences[0].id, "RABGLTR")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 39)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.35)
        self.assertAlmostEqual(alignment.annotations["bit score"], 24.9)
        self.assertEqual(
            str(alignment),
            """\
RABGLTR        1116 ????????????????????????????????????????????????????????????
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pGT875          242 ????????????????????????????????????????????????????????????

RABGLTR        1176 ???????????????????????? 1200
                 60 ||||||||||||||||||||||||   84
pGT875          182 ????????????????????????  158
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[1116, 1200], [242, 158]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 1200)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "GCATGGCTGGGTGGGGCAGGATTAGTGTGGGGGGAGTTGGGTGCTCAGGCAGGGCTATGAGGGATCTTGTTCATTTCCGGGCCC",
        )
        self.assertEqual(
            alignment[1],
            "GCAAGGTAGCGCAGGATGGCATTGCTCTGGGTGATCTTGTGTGATCCATCGATCAAGTAAGGCAGATTGGGAAAGTCCAGGCCC",
        )
        # pGT875   pGT875
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['G', 'C', 'A', 'T', 'G', 'G', 'C', 'T', 'G', 'G', 'G', 'T', 'G',
           'G', 'G', 'G', 'C', 'A', 'G', 'G', 'A', 'T', 'T', 'A', 'G', 'T',
           'G', 'T', 'G', 'G', 'G', 'G', 'G', 'G', 'A', 'G', 'T', 'T', 'G',
           'G', 'G', 'T', 'G', 'C', 'T', 'C', 'A', 'G', 'G', 'C', 'A', 'G',
           'G', 'G', 'C', 'T', 'A', 'T', 'G', 'A', 'G', 'G', 'G', 'A', 'T',
           'C', 'T', 'T', 'G', 'T', 'T', 'C', 'A', 'T', 'T', 'T', 'C', 'C',
           'G', 'G', 'G', 'C', 'C', 'C'],
          ['G', 'C', 'A', 'A', 'G', 'G', 'T', 'A', 'G', 'C', 'G', 'C', 'A',
           'G', 'G', 'A', 'T', 'G', 'G', 'C', 'A', 'T', 'T', 'G', 'C', 'T',
           'C', 'T', 'G', 'G', 'G', 'T', 'G', 'A', 'T', 'C', 'T', 'T', 'G',
           'T', 'G', 'T', 'G', 'A', 'T', 'C', 'C', 'A', 'T', 'C', 'G', 'A',
           'T', 'C', 'A', 'A', 'G', 'T', 'A', 'A', 'G', 'G', 'C', 'A', 'G',
           'A', 'T', 'T', 'G', 'G', 'G', 'A', 'A', 'A', 'G', 'T', 'C', 'C',
           'A', 'G', 'G', 'C', 'C', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (84 aligned letters; 45 identities; 39 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 84:
        identities = 45,
        mismatches = 39.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 84)
        self.assertEqual(counts.identities, 45)
        self.assertEqual(counts.mismatches, 39)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
        self.assertEqual(alignment.annotations["gap opens"], 0)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 10)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 10)
        self.assertEqual(alignment.shape, (2, 10 + 0))
        self.assertEqual(alignment.sequences[0].id, "pGT875")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 0)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.35)
        self.assertAlmostEqual(alignment.annotations["bit score"], 24.9)
        self.assertEqual(
            str(alignment),
            """\
pGT875          792 ?????????? 802
                  0 ||||||||||  10
pGT875          310 ?????????? 300
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                np.array([[792, 802], [310, 300]]),
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 802)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(alignment[0], "CCTGGTTCTC")
        self.assertEqual(alignment[1], "CCTGGTTCTC")
        # pGT875   BTGST
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'C', 'T', 'G', 'G', 'T', 'T', 'C', 'T', 'C'],
          ['C', 'C', 'T', 'G', 'G', 'T', 'T', 'C', 'T', 'C']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (10 aligned letters; 10 identities; 0 mismatches; 0 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 10:
        identities = 10,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 0)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 0)
        self.assertEqual(counts.insertions, 0)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 0)
        self.assertEqual(counts.aligned, 10)
        self.assertEqual(counts.identities, 10)
        self.assertEqual(counts.mismatches, 0)
        alignment = next(alignments)
        self.assertEqual(len(alignment), 2)
        self.assertAlmostEqual(alignment.annotations["% identity"], 59.15)
        self.assertEqual(alignment.annotations["gap opens"], 3)
        aligned = alignment.aligned
        self.assertEqual(sum(end - start for start, end in aligned[0]), 71)
        self.assertEqual(sum(start - end for start, end in aligned[1]), 71)
        self.assertEqual(alignment.shape, (2, 71 + 3))
        self.assertEqual(alignment.sequences[0].id, "BTGST")
        self.assertEqual(alignment.sequences[1].id, "pGT875")
        self.assertEqual(alignment.annotations["mismatches"], 29)
        self.assertAlmostEqual(alignment.annotations["evalue"], 0.68)
        self.assertAlmostEqual(alignment.annotations["bit score"], 23.9)
        self.assertEqual(
            str(alignment),
            """\
BTGST           280 ????????????????????????-????????--?????????????????????????
                  0 ||||||||||||||||||||||||-||||||||--|||||||||||||||||||||||||
pGT875          378 ????????????????????????????????????????????????????????????

BTGST           337 ?????????????? 351
                 60 ||||||||||||||  74
pGT875          318 ?????????????? 304
""",
        )
        self.assertTrue(
            np.array_equal(
                alignment.coordinates,
                # fmt: off
                np.array([[280, 304, 304, 312, 312, 351],
                          [378, 354, 353, 345, 343, 304]])
                # fmt: on
            )
        )
        query = self.query
        target = self.targets[alignment.sequences[0].id]
        self.assertEqual(len(alignment.sequences[0].seq), 351)
        self.assertEqual(len(alignment.sequences[1].seq), len(query))
        alignment.sequences[0].seq = target
        alignment.sequences[1].seq = query
        self.assertEqual(
            alignment[0],
            "CTGCGGCACCTGGGCCGCACCCTC-GGGCTGTA--TGGGAAGGACCAGCAGGAGGCGGCCCTGGTGGACATGGT",
        )
        self.assertEqual(
            alignment[1],
            "CTCTGGCTTCTGCTTCTCAAAGTCAGGGTTGTAACAGAGCATGATGAGCTGCATGCGGGTGTCCATGACCTGGT",
        )
        self.assertTrue(
            np.array_equal(
                np.array(alignment, "U"),
                # fmt: off
np.array([['C', 'T', 'G', 'C', 'G', 'G', 'C', 'A', 'C', 'C', 'T', 'G', 'G',
           'G', 'C', 'C', 'G', 'C', 'A', 'C', 'C', 'C', 'T', 'C', '-', 'G',
           'G', 'G', 'C', 'T', 'G', 'T', 'A', '-', '-', 'T', 'G', 'G', 'G',
           'A', 'A', 'G', 'G', 'A', 'C', 'C', 'A', 'G', 'C', 'A', 'G', 'G',
           'A', 'G', 'G', 'C', 'G', 'G', 'C', 'C', 'C', 'T', 'G', 'G', 'T',
           'G', 'G', 'A', 'C', 'A', 'T', 'G', 'G', 'T'],
          ['C', 'T', 'C', 'T', 'G', 'G', 'C', 'T', 'T', 'C', 'T', 'G', 'C',
           'T', 'T', 'C', 'T', 'C', 'A', 'A', 'A', 'G', 'T', 'C', 'A', 'G',
           'G', 'G', 'T', 'T', 'G', 'T', 'A', 'A', 'C', 'A', 'G', 'A', 'G',
           'C', 'A', 'T', 'G', 'A', 'T', 'G', 'A', 'G', 'C', 'T', 'G', 'C',
           'A', 'T', 'G', 'C', 'G', 'G', 'G', 'T', 'G', 'T', 'C', 'C', 'A',
           'T', 'G', 'A', 'C', 'C', 'T', 'G', 'G', 'T']], dtype='U')
                # fmt: on
            )
        )
        counts = alignment.counts()
        self.assertEqual(
            repr(counts),
            "<AlignmentCounts object (71 aligned letters; 42 identities; 29 mismatches; 3 gaps) at 0x%x>"
            % id(counts),
        )
        self.assertEqual(
            str(counts),
            """\
AlignmentCounts object with
    aligned = 71:
        identities = 42,
        mismatches = 29.
    gaps = 3:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 3:
            internal_insertions = 3:
                open_internal_insertions = 2,
                extend_internal_insertions = 1;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
        )
        self.assertEqual(counts.left_insertions, 0)
        self.assertEqual(counts.left_deletions, 0)
        self.assertEqual(counts.right_insertions, 0)
        self.assertEqual(counts.right_deletions, 0)
        self.assertEqual(counts.internal_insertions, 3)
        self.assertEqual(counts.internal_deletions, 0)
        self.assertEqual(counts.left_gaps, 0)
        self.assertEqual(counts.right_gaps, 0)
        self.assertEqual(counts.internal_gaps, 3)
        self.assertEqual(counts.insertions, 3)
        self.assertEqual(counts.deletions, 0)
        self.assertEqual(counts.gaps, 3)
        self.assertEqual(counts.aligned, 71)
        self.assertEqual(counts.identities, 42)
        self.assertEqual(counts.mismatches, 29)
        with self.assertRaises(StopIteration):
            next(alignments)


class TestFastaBasic(unittest.TestCase):
    def test_empty(self):
        import io

        stream = io.StringIO()
        with self.assertRaisesRegex(ValueError, "Empty file."):
            Align.parse(stream, "tabular")


class TestBlast(unittest.TestCase):
    def test_2226_tblastn_001(self):
        path = "Blast/tab_2226_tblastn_001.txt"
        with open(path) as stream:
            with self.assertRaisesRegex(ValueError, "Missing header."):
                Align.parse(stream, "tabular")

    def test_2226_tblastn_002(self):
        path = "Blast/tab_2226_tblastn_002.txt"
        with open(path) as stream:
            with self.assertRaisesRegex(ValueError, "Empty file."):
                Align.parse(stream, "tabular")

    def test_2226_tblastn_003(self):
        path = "Blast/tab_2226_tblastn_003.txt"
        with open(path) as stream:
            with self.assertRaisesRegex(ValueError, "Missing header."):
                Align.parse(stream, "tabular")

    def test_2226_tblastn_004(self):
        path = "Blast/tab_2226_tblastn_004.txt"
        with open(path) as stream:
            with self.assertRaisesRegex(ValueError, "Missing header."):
                Align.parse(stream, "tabular")

    def test_2226_tblastn_005(self):
        path = "Blast/tab_2226_tblastn_005.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["Database"], "db/minirefseq_mrna")
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|145479850|ref|XM_001425911.1|")
            self.assertEqual(alignment.query.annotations["start"], 30)
            self.assertEqual(alignment.query.annotations["end"], 73)
            self.assertEqual(alignment.target.annotations["start"], 1743)
            self.assertEqual(alignment.target.annotations["end"], 1872)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.88)
            self.assertEqual(alignment.annotations["alignment length"], 43)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|72012412|ref|XM_777959.1|")
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|115975252|ref|XM_001180111.1|")
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 94)
            self.assertEqual(alignment.target.annotations["end"], 388)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 199)
            self.assertAlmostEqual(alignment.annotations["% identity"], 95.92)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 4)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 29)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 541)
            self.assertEqual(alignment.target.annotations["end"], 754)
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 32.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 29.58)
            self.assertEqual(alignment.annotations["alignment length"], 71)
            self.assertEqual(alignment.annotations["mismatches"], 46)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 77)
            self.assertEqual(alignment.target.annotations["end"], 371)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 803)
            self.assertEqual(alignment.target.annotations["end"], 1103)
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 160)
            self.assertEqual(alignment.target.annotations["end"], 454)
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 865)
            self.assertEqual(alignment.target.annotations["end"], 1165)
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 172)
            self.assertEqual(alignment.target.annotations["end"], 466)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-66, places=66)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 898)
            self.assertEqual(alignment.target.annotations["end"], 1198)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 63)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 11)
            self.assertEqual(alignment.query.annotations["end"], 54)
            self.assertEqual(alignment.target.annotations["start"], 3180)
            self.assertEqual(alignment.target.annotations["end"], 3336)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 19.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.77)
            self.assertEqual(alignment.annotations["alignment length"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2226_tblastn_007(self):
        path = "Blast/tab_2226_tblastn_007.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["Database"], "db/minirefseq_mrna")
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|145479850|ref|XM_001425911.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["start"], 30)
            self.assertEqual(alignment.query.annotations["end"], 73)
            self.assertEqual(alignment.target.annotations["start"], 1743)
            self.assertEqual(alignment.target.annotations["end"], 1872)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.88)
            self.assertEqual(alignment.annotations["alignment length"], 43)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|72012412|ref|XM_777959.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|115975252|ref|XM_001180111.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2226_tblastn_008(self):
        path = "Blast/tab_2226_tblastn_008.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["Database"], "db/minirefseq_mrna")

            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 94)
            self.assertEqual(alignment.target.annotations["end"], 388)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 199)
            self.assertAlmostEqual(alignment.annotations["% identity"], 95.92)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 4)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 29)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 541)
            self.assertEqual(alignment.target.annotations["end"], 754)
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 32.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 29.58)
            self.assertEqual(alignment.annotations["alignment length"], 71)
            self.assertEqual(alignment.annotations["mismatches"], 46)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 77)
            self.assertEqual(alignment.target.annotations["end"], 371)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 803)
            self.assertEqual(alignment.target.annotations["end"], 1103)
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 160)
            self.assertEqual(alignment.target.annotations["end"], 454)
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 865)
            self.assertEqual(alignment.target.annotations["end"], 1165)
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 172)
            self.assertEqual(alignment.target.annotations["end"], 466)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-66, places=66)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 898)
            self.assertEqual(alignment.target.annotations["end"], 1198)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 63)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 11)
            self.assertEqual(alignment.query.annotations["end"], 54)
            self.assertEqual(alignment.target.annotations["start"], 3180)
            self.assertEqual(alignment.target.annotations["end"], 3336)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 19.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.77)
            self.assertEqual(alignment.annotations["alignment length"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2226_tblastn_009(self):
        path = "Blast/tab_2226_tblastn_009.txt"
        with open(path) as stream:
            with self.assertRaisesRegex(ValueError, "Missing header."):
                Align.parse(stream, "tabular")

    def test_2226_tblastn_010(self):
        path = "Blast/tab_2226_tblastn_010.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["Database"], "db/minirefseq_mrna")

            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|145479850|ref|XM_001425911.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.7)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|72012412|ref|XM_777959.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|115975252|ref|XM_001180111.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 199)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 32.7)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-66, places=66)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.6)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 19.6)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2226_tblastn_011(self):
        path = "Blast/tab_2226_tblastn_011.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["Database"], "db/minirefseq_mrna")
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(
                alignment.query.annotations["acc."], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(len(alignment.query.seq), 102)
            self.assertEqual(alignment.target.id, "gi|145479850|ref|XM_001425911.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|145479850|ref|XM_001425911.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|145479850|ref|XM_001425911.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|145479850|ref|XM_001425911.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 4632)
            self.assertEqual(
                str(alignment),
                """\
gi|145479         0 PKTATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*KDID 43
                  0 |.....||.||..||...|||.........||...|....|.| 43
gi|160806        30 PDSNIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTSDLD 73
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    np.array([[0, 43], [30, 73]]),
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 1743)
            self.assertEqual(alignment.target.annotations["end"], 1872)
            self.assertEqual(
                alignment.target.seq, "PKTATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*KDID"
            )
            self.assertEqual(
                alignment.query.seq[30:73],
                "PDSNIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTSDLD",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.7)
            self.assertAlmostEqual(alignment.score, 78)
            self.assertEqual(alignment.shape, (2, 43))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.88)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.47)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/1")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 77.0; 43 aligned letters; 15 identities; 28 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 77.0,
    aligned = 43:
        identities = 15,
        positives = 26,
        mismatches = 28.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 43)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 28)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(
                alignment.query.annotations["acc."], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(len(alignment.query.seq), 102)
            self.assertEqual(alignment.target.id, "gi|72012412|ref|XM_777959.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|72012412|ref|XM_777959.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|72012412|ref|XM_777959.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"], "gi|72012412|ref|XM_777959.1|"
            )
            self.assertEqual(alignment.target.annotations["length"], 1593)
            self.assertEqual(
                str(alignment),
                """\
gi|720124         0 GLVPDHTLILPVGHYQSMLDLTEEVQTELDQFKSALRKYYLSKGKTCVIYERNFRTQHL
                  0 ||...||....|......||.|||....||.|.|.--------.|....||.|...|.|
gi|160806        43 GLADTHTIEVTVDNEPVSLDITEESTSDLDKFNSG--------DKVTITYEKNDEGQLL

gi|720124        59
                 59
gi|160806        94
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 35, 43, 59],
                              [43, 78, 78, 94]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertEqual(
                alignment.target.seq,
                "GLVPDHTLILPVGHYQSMLDLTEEVQTELDQFKSALRKYYLSKGKTCVIYERNFRTQHL",
            )
            self.assertEqual(
                alignment.query.seq[43:94],
                "GLADTHTIEVTVDNEPVSLDITEESTSDLDKFNSGDKVTITYEKNDEGQLL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 59))
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            self.assertEqual(alignment.annotations["gaps"], 8)
            self.assertAlmostEqual(alignment.annotations["% positives"], 49.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/1")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 51 aligned letters; 20 identities; 31 mismatches; 29 positives; 8 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 51:
        identities = 20,
        positives = 29,
        mismatches = 31.
    gaps = 8:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 8:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 8:
                open_internal_deletions = 1,
                extend_internal_deletions = 7;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 8)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 8)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 8)
            self.assertEqual(counts.gaps, 8)
            self.assertEqual(counts.aligned, 51)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 31)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(
                alignment.query.description,
                "membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168]",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(
                alignment.query.annotations["acc."], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|16080617|ref|NP_391444.1|"
            )
            self.assertEqual(len(alignment.query.seq), 102)
            self.assertEqual(alignment.target.id, "gi|115975252|ref|XM_001180111.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|115975252|ref|XM_001180111.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|115975252|ref|XM_001180111.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|115975252|ref|XM_001180111.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1593)
            self.assertEqual(
                str(alignment),
                """\
gi|115975         0 GLVPDHTLILPVGHYQSMLDLTEEVQTELDQFKSALRKYYLSKGKTCVIYERNFRTQHL
                  0 ||...||....|......||.|||....||.|.|.--------.|....||.|...|.|
gi|160806        43 GLADTHTIEVTVDNEPVSLDITEESTSDLDKFNSG--------DKVTITYEKNDEGQLL

gi|115975        59
                 59
gi|160806        94
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 35, 43, 59],
                              [43, 78, 78, 94]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertEqual(
                alignment.target.seq,
                "GLVPDHTLILPVGHYQSMLDLTEEVQTELDQFKSALRKYYLSKGKTCVIYERNFRTQHL",
            )
            self.assertEqual(
                alignment.query.seq[43:94],
                "GLADTHTIEVTVDNEPVSLDITEESTSDLDKFNSGDKVTITYEKNDEGQLL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 59))
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            self.assertEqual(alignment.annotations["gaps"], 8)
            self.assertAlmostEqual(alignment.annotations["% positives"], 49.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/1")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 51 aligned letters; 20 identities; 31 mismatches; 29 positives; 8 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 51:
        identities = 20,
        positives = 29,
        mismatches = 31.
    gaps = 8:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 8:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 8:
                open_internal_deletions = 1,
                extend_internal_deletions = 7;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 8)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 8)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 8)
            self.assertEqual(counts.gaps, 8)
            self.assertEqual(counts.aligned, 51)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 31)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350596019|ref|XM_003360601.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|350596019|ref|XM_003360601.2|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|350596019|ref|XM_003360601.2|",
            )
            self.assertEqual(alignment.target.annotations["length"], 772)
            self.assertEqual(
                str(alignment),
                """\
gi|350596         0 KRIREGYLVKKGSMFNTWKPMWVILLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG
                  0 |||||||||||||.|||||||||.||||||||||||||||||||||||||||||||||||
gi|114649         0 KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG

gi|350596        60 KRMFVFKITTTKQQDHFFQAAFLEERDGWVRDIKKAIK 98
                 60 |||||.|||||||||||||||||||||.|||||||||| 98
gi|114649        60 KRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
""",
            )
            self.assertTrue(
                np.array_equal(alignment.coordinates, np.array([[0, 98], [0, 98]]))
            )
            self.assertEqual(alignment.target.annotations["start"], 94)
            self.assertEqual(alignment.target.annotations["end"], 388)
            self.assertEqual(
                alignment.target.seq,
                "KRIREGYLVKKGSMFNTWKPMWVILLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVFKITTTKQQDHFFQAAFLEERDGWVRDIKKAIK",
            )
            self.assertEqual(
                alignment.query.seq[0:98],
                "KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 199)
            self.assertAlmostEqual(alignment.score, 506)
            self.assertEqual(alignment.shape, (2, 98))
            self.assertAlmostEqual(alignment.annotations["% identity"], 95.92)
            self.assertEqual(alignment.annotations["identical"], 94)
            self.assertEqual(alignment.annotations["mismatches"], 4)
            self.assertEqual(alignment.annotations["positives"], 96)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 97.96)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 508.0; 98 aligned letters; 94 identities; 4 mismatches; 96 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 508.0,
    aligned = 98:
        identities = 94,
        positives = 96,
        mismatches = 4.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 98)
            self.assertEqual(counts.identities, 94)
            self.assertEqual(counts.mismatches, 4)
            self.assertEqual(counts.positives, 96)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350596019|ref|XM_003360601.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|350596019|ref|XM_003360601.2|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|350596019|ref|XM_003360601.2|",
            )
            self.assertEqual(alignment.target.annotations["length"], 772)
            self.assertEqual(
                str(alignment),
                """\
gi|350596         0 LHYYDPAGGEDPLGAIHLRGCVVTSVESNTDGKNGFLWERAXXITADEVHYFLQAANPKE
                  0 ...|.......|.|.|.|.|...||-.....||..|...---..|......|.|||...|
gi|114649        29 IEFYKKKSDNSPKGMIPLKGSTLTS-PCQDFGKRMFVLK---ITTTKQQDHFFQAAFLEE

gi|350596        60 RTEWIKAIQVA 71
                 60 |..|...|..| 71
gi|114649        85 RDAWVRDIKKA 96
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 25, 26, 39, 42, 71],
                              [29, 54, 54, 67, 67, 96]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 541)
            self.assertEqual(alignment.target.annotations["end"], 754)
            self.assertEqual(
                alignment.target.seq,
                "LHYYDPAGGEDPLGAIHLRGCVVTSVESNTDGKNGFLWERAXXITADEVHYFLQAANPKERTEWIKAIQVA",
            )
            self.assertEqual(
                alignment.query.seq[29:96],
                "IEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 32.7)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 71))
            self.assertAlmostEqual(alignment.annotations["% identity"], 29.58)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 46)
            self.assertEqual(alignment.annotations["positives"], 33)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            self.assertEqual(alignment.annotations["gaps"], 4)
            self.assertAlmostEqual(alignment.annotations["% positives"], 46.48)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 95.0; 67 aligned letters; 21 identities; 46 mismatches; 33 positives; 4 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 95.0,
    aligned = 67:
        identities = 21,
        positives = 33,
        mismatches = 46.
    gaps = 4:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 4:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 4:
                open_internal_deletions = 2,
                extend_internal_deletions = 2;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 4)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 4)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 4)
            self.assertEqual(counts.gaps, 4)
            self.assertEqual(counts.aligned, 67)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 46)
            self.assertEqual(counts.positives, 33)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|301779869|ref|XM_002925302.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|301779869|ref|XM_002925302.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|301779869|ref|XM_002925302.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1144)
            self.assertEqual(
                str(alignment),
                """\
gi|301779         0 KRIREGYLVKRGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG
                  0 ||||||||||.|||||||||||||||||||||||||||||||||||||||||||||||||
gi|114649         0 KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG

gi|301779        60 KRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
                 60 |||||.|||||||||||||||||||||||||||||||| 98
gi|114649        60 KRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    np.array([[0, 98], [0, 98]]),
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 77)
            self.assertEqual(alignment.target.annotations["end"], 371)
            self.assertEqual(
                alignment.target.seq,
                "KRIREGYLVKRGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertEqual(
                alignment.query.seq[0:98],
                "KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.score, 515)
            self.assertEqual(alignment.shape, (2, 98))
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["identical"], 96)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["positives"], 97)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 98.98)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/3")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 513.0; 98 aligned letters; 96 identities; 2 mismatches; 97 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 513.0,
    aligned = 98:
        identities = 96,
        positives = 97,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 98)
            self.assertEqual(counts.identities, 96)
            self.assertEqual(counts.mismatches, 2)
            self.assertEqual(counts.positives, 97)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|301779869|ref|XM_002925302.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|301779869|ref|XM_002925302.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|301779869|ref|XM_002925302.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1144)
            self.assertEqual(
                str(alignment),
                """\
gi|301779         0 IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGEDPLGAIHLRGCVVTSVESNPD
                  0 |..|.|.|.|.....||.....|.||.--...|.......|.|.|.|.|...||----|.
gi|114649         2 IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNSPKGMIPLKGSTLTS----PC

gi|301779        60 VRKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA 100
                 60 ...........|.|......|.|||...||..|...|..| 100
gi|114649        56 QDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA  96
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[0, 27, 29, 54, 58, 100],
                              [2, 29, 29, 54, 54,  96]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 803)
            self.assertEqual(alignment.target.annotations["end"], 1103)
            self.assertEqual(
                alignment.target.seq,
                "IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGEDPLGAIHLRGCVVTSVESNPDVRKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA",
            )
            self.assertEqual(
                alignment.query.seq[2:96],
                "IREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 105)
            self.assertEqual(alignment.shape, (2, 100))
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["identical"], 30)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["positives"], 48)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            self.assertEqual(alignment.annotations["gaps"], 6)
            self.assertAlmostEqual(alignment.annotations["% positives"], 48.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/3")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 133.0; 94 aligned letters; 30 identities; 64 mismatches; 48 positives; 6 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 133.0,
    aligned = 94:
        identities = 30,
        positives = 48,
        mismatches = 64.
    gaps = 6:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 6:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 6:
                open_internal_deletions = 2,
                extend_internal_deletions = 4;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 6)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 6)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 6)
            self.assertEqual(counts.gaps, 6)
            self.assertEqual(counts.aligned, 94)
            self.assertEqual(counts.identities, 30)
            self.assertEqual(counts.mismatches, 64)
            self.assertEqual(counts.positives, 48)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|296223671|ref|XM_002757683.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|296223671|ref|XM_002757683.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|296223671|ref|XM_002757683.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1183)
            self.assertEqual(
                str(alignment),
                """\
gi|296223         0 KRIREGYLVKKGSMFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG
                  0 |||||||||||||.||||||||||||||||||||||||||||||||||||||||||||||
gi|114649         0 KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG

gi|296223        60 KRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
                 60 |||||.|||||||||||||||||||||||||||||||| 98
gi|114649        60 KRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    np.array([[0, 98], [0, 98]]),
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 160)
            self.assertEqual(alignment.target.annotations["end"], 454)
            self.assertEqual(
                alignment.target.seq,
                "KRIREGYLVKKGSMFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertEqual(
                alignment.query.seq[0:98],
                "KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-67, places=67)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.score, 515)
            self.assertEqual(alignment.shape, (2, 98))
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["identical"], 96)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["positives"], 97)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 98.98)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 513.0; 98 aligned letters; 96 identities; 2 mismatches; 97 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 513.0,
    aligned = 98:
        identities = 96,
        positives = 97,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 98)
            self.assertEqual(counts.identities, 96)
            self.assertEqual(counts.mismatches, 2)
            self.assertEqual(counts.positives, 97)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|296223671|ref|XM_002757683.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|296223671|ref|XM_002757683.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|296223671|ref|XM_002757683.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|296223671|ref|XM_002757683.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1183)
            self.assertEqual(
                str(alignment),
                """\
gi|296223         0 IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGEDPLGAIHLRGCVVTSVESNSD
                  0 |..|.|.|.|.....||.....|.||.--...|.......|.|.|.|.|...||......
gi|114649         2 IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG

gi|296223        60 GRKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA 100
                 60 .|..----...|.|......|.|||...||..|...|..| 100
gi|114649        60 KRMF----VLKITTTKQQDHFFQAAFLEERDAWVRDIKKA  96
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[0, 27, 29, 64, 68, 100],
                              [2, 29, 29, 64, 64,  96]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 865)
            self.assertEqual(alignment.target.annotations["end"], 1165)
            self.assertEqual(
                alignment.target.seq,
                "IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGEDPLGAIHLRGCVVTSVESNSDGRKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA",
            )
            self.assertEqual(
                alignment.query.seq[2:96],
                "IREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 105)
            self.assertEqual(alignment.shape, (2, 100))
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["identical"], 30)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["positives"], 48)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            self.assertEqual(alignment.annotations["gaps"], 6)
            self.assertAlmostEqual(alignment.annotations["% positives"], 48.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 132.0; 94 aligned letters; 30 identities; 64 mismatches; 48 positives; 6 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 132.0,
    aligned = 94:
        identities = 30,
        positives = 48,
        mismatches = 64.
    gaps = 6:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 6:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 6:
                open_internal_deletions = 2,
                extend_internal_deletions = 4;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 6)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 6)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 6)
            self.assertEqual(counts.gaps, 6)
            self.assertEqual(counts.aligned, 94)
            self.assertEqual(counts.identities, 30)
            self.assertEqual(counts.mismatches, 64)
            self.assertEqual(counts.positives, 48)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|338714227|ref|XM_001492113.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|338714227|ref|XM_001492113.3|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|338714227|ref|XM_001492113.3|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1390)
            self.assertEqual(
                str(alignment),
                """\
gi|338714         0 KRIREGYLVKRGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG
                  0 ||||||||||.|||||||||||||||||||||||||||||||||||||||||||||||||
gi|114649         0 KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFG

gi|338714        60 KRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
                 60 |||||.|||||||||||||||||||||||||||||||| 98
gi|114649        60 KRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK 98
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    np.array([[0, 98], [0, 98]]),
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 172)
            self.assertEqual(alignment.target.annotations["end"], 466)
            self.assertEqual(
                alignment.target.seq,
                "KRIREGYLVKRGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertEqual(
                alignment.query.seq[0:98],
                "KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-66, places=66)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.score, 515)
            self.assertEqual(alignment.shape, (2, 98))
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["identical"], 96)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["positives"], 97)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 98.98)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 513.0; 98 aligned letters; 96 identities; 2 mismatches; 97 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 513.0,
    aligned = 98:
        identities = 96,
        positives = 97,
        mismatches = 2.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 98)
            self.assertEqual(counts.identities, 96)
            self.assertEqual(counts.mismatches, 2)
            self.assertEqual(counts.positives, 97)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|338714227|ref|XM_001492113.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|338714227|ref|XM_001492113.3|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|338714227|ref|XM_001492113.3|",
            )
            self.assertEqual(alignment.target.annotations["length"], 1390)
            self.assertEqual(
                str(alignment),
                """\
gi|338714         0 IKQGCLLKQGHRRKNWKVRKFVLREDPAYVHYYDPAGGEEPLGAIHLRGCVVTSVEGNPD
                  0 |..|.|.|.|.....||....||.||.--...|.......|.|.|.|.|...||----|.
gi|114649         2 IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNSPKGMIPLKGSTLTS----PC

gi|338714        60 GKKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA 100
                 60 ...........|.|......|.|||...||..|...|..| 100
gi|114649        56 QDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA  96
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[0, 27, 29, 54, 58, 100],
                              [2, 29, 29, 54, 54,  96]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 898)
            self.assertEqual(alignment.target.annotations["end"], 1198)
            self.assertEqual(
                alignment.target.seq,
                "IKQGCLLKQGHRRKNWKVRKFVLREDPAYVHYYDPAGGEEPLGAIHLRGCVVTSVEGNPDGKKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA",
            )
            self.assertEqual(
                alignment.query.seq[2:96],
                "IREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTSPCQDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.6)
            self.assertAlmostEqual(alignment.score, 109)
            self.assertEqual(alignment.shape, (2, 100))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.00)
            self.assertEqual(alignment.annotations["identical"], 31)
            self.assertEqual(alignment.annotations["mismatches"], 63)
            self.assertEqual(alignment.annotations["positives"], 48)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            self.assertEqual(alignment.annotations["gaps"], 6)
            self.assertAlmostEqual(alignment.annotations["% positives"], 48.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/2")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 136.0; 94 aligned letters; 31 identities; 63 mismatches; 48 positives; 6 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 136.0,
    aligned = 94:
        identities = 31,
        positives = 48,
        mismatches = 63.
    gaps = 6:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 6:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 6:
                open_internal_deletions = 2,
                extend_internal_deletions = 4;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 6)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 6)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 6)
            self.assertEqual(counts.gaps, 6)
            self.assertEqual(counts.aligned, 94)
            self.assertEqual(counts.identities, 31)
            self.assertEqual(counts.mismatches, 63)
            self.assertEqual(counts.positives, 48)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|11464971:4-101")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|11464971:4-101"
            )
            self.assertEqual(len(alignment.query.seq), 98)
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "0")
            self.assertEqual(alignment.target.annotations["gis"], "0")
            self.assertEqual(
                alignment.target.annotations["acc."], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(
                alignment.target.annotations["acc.ver"],
                "gi|365982352|ref|XM_003667962.1|",
            )
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 GSCFPTWDLIFIEVLNPFLKEKLWEADNEEISKFVDLTLKGLVDLYPSHFTS 52
                  0 ||.|.||.......|---------|...|...|..|...||...|..|..|| 52
gi|114649        11 GSVFNTWKPMWVVLL---------EDGIEFYKKKSDNSPKGMIPLKGSTLTS 54
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 15, 24, 52],
                              [11, 26, 26, 54]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.target.annotations["start"], 3180)
            self.assertEqual(alignment.target.annotations["end"], 3336)
            self.assertEqual(
                alignment.target.seq,
                "GSCFPTWDLIFIEVLNPFLKEKLWEADNEEISKFVDLTLKGLVDLYPSHFTS",
            )
            self.assertEqual(
                alignment.query.seq[11:54],
                "GSVFNTWKPMWVVLLEDGIEFYKKKSDNSPKGMIPLKGSTLTS",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 19.6)
            self.assertAlmostEqual(alignment.score, 39)
            self.assertEqual(alignment.shape, (2, 52))
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.77)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            self.assertEqual(alignment.annotations["gaps"], 9)
            self.assertAlmostEqual(alignment.annotations["% positives"], 44.23)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "0/1")
            self.assertEqual(alignment.query.annotations["frame"], "0")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 60.0; 43 aligned letters; 16 identities; 27 mismatches; 23 positives; 9 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 60.0,
    aligned = 43:
        identities = 16,
        positives = 23,
        mismatches = 27.
    gaps = 9:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 9:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 9:
                open_internal_deletions = 1,
                extend_internal_deletions = 8;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 9)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 9)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 9)
            self.assertEqual(counts.gaps, 9)
            self.assertEqual(counts.aligned, 43)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 23)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2226_tblastn_012(self):
        path = "Blast/tab_2226_tblastn_012.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.26+")
            self.assertEqual(alignments.metadata["RID"], "X76FDCG9016")
            self.assertEqual(alignments.metadata["Database"], "refseq_rna")

            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|145479850|ref|XM_001425911.1|")
            self.assertEqual(alignment.query.annotations["start"], 30)
            self.assertEqual(alignment.query.annotations["end"], 73)
            self.assertEqual(alignment.target.annotations["start"], 1743)
            self.assertEqual(alignment.target.annotations["end"], 1872)
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.76)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.88)
            self.assertEqual(alignment.annotations["alignment length"], 43)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|115975252|ref|XM_001180111.1|")
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1056)
            self.assertEqual(alignment.target.annotations["end"], 1233)
            self.assertAlmostEqual(alignment.annotations["evalue"], 7.2)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|16080617|ref|NP_391444.1|")
            self.assertEqual(alignment.target.id, "gi|390342090|ref|XM_777959.2|")
            self.assertEqual(alignment.query.annotations["start"], 43)
            self.assertEqual(alignment.query.annotations["end"], 94)
            self.assertEqual(alignment.target.annotations["start"], 1266)
            self.assertEqual(alignment.target.annotations["end"], 1443)
            self.assertAlmostEqual(alignment.annotations["evalue"], 7.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.90)
            self.assertEqual(alignment.annotations["alignment length"], 59)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 1)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|354480463|ref|XM_003502378.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 75)
            self.assertEqual(alignment.target.annotations["end"], 369)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-63, places=63)
            self.assertAlmostEqual(alignment.annotations["bit score"], 205)
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|354480463|ref|XM_003502378.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 801)
            self.assertEqual(alignment.target.annotations["end"], 1101)
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 43.9)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 3)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 94)
            self.assertEqual(alignment.target.annotations["end"], 388)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-62, places=62)
            self.assertAlmostEqual(alignment.annotations["bit score"], 199)
            self.assertAlmostEqual(alignment.annotations["% identity"], 95.92)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 4)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|350596019|ref|XM_003360601.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 29)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 541)
            self.assertEqual(alignment.target.annotations["end"], 754)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 32.7)
            self.assertAlmostEqual(alignment.annotations["% identity"], 29.58)
            self.assertEqual(alignment.annotations["alignment length"], 71)
            self.assertEqual(alignment.annotations["mismatches"], 46)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 77)
            self.assertEqual(alignment.target.annotations["end"], 371)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-62, places=62)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|301779869|ref|XM_002925302.1|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 803)
            self.assertEqual(alignment.target.annotations["end"], 1103)
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 64)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 172)
            self.assertEqual(alignment.target.annotations["end"], 466)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-61, places=61)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|338714227|ref|XM_001492113.3|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 96)
            self.assertEqual(alignment.target.annotations["start"], 898)
            self.assertEqual(alignment.target.annotations["end"], 1198)
            self.assertAlmostEqual(alignment.annotations["evalue"], 9e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.6)
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.00)
            self.assertEqual(alignment.annotations["alignment length"], 100)
            self.assertEqual(alignment.annotations["mismatches"], 63)
            self.assertEqual(alignment.annotations["gap opens"], 2)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|11464971:4-101")
            self.assertEqual(alignment.target.id, "gi|390474391|ref|XM_002757683.2|")
            self.assertEqual(alignment.query.description, "pleckstrin [Mus musculus]")
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 98)
            self.assertEqual(alignment.target.annotations["start"], 160)
            self.assertEqual(alignment.target.annotations["end"], 454)
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-61, places=61)
            self.assertAlmostEqual(alignment.annotations["bit score"], 202)
            self.assertAlmostEqual(alignment.annotations["% identity"], 97.96)
            self.assertEqual(alignment.annotations["alignment length"], 98)
            self.assertEqual(alignment.annotations["mismatches"], 2)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2228_tblastn_001(self):
        path = "Blast/tab_2228_tblastn_001.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTN")
            self.assertEqual(alignments.metadata["Version"], "2.2.28+")
            self.assertEqual(alignments.metadata["RID"], "M6BMVNA2015")
            self.assertEqual(alignments.metadata["Database"], "nr")

            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|148227873|ref|NM_001095167.1|;gi|55250552|gb|BC086280.1|",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|512812550|ref|XM_002935781.2|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|512812554|ref|XM_004910718.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|327289356|ref|XM_003229343.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|602661018|ref|XM_007436108.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|564242014|ref|XM_006277753.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.0)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|591387858|ref|XM_007068281.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-180, places=180)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|558185265|ref|XM_006128143.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-180, places=180)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|573878747|ref|XM_006627536.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-173, places=173)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            alignment = next(alignments)
            self.assertEqual(alignment.query.id, "gi|148227874|ref|NP_001088636.1|")
            self.assertEqual(alignment.query.description, "sirtuin 2 [Xenopus laevis]")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410910671|ref|XM_003968765.1|"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-173, places=173)
            counts = alignment.counts()
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (0 aligned letters; 0 identities; 0 mismatches; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    aligned = 0:
        identities = 0,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 0)
            self.assertEqual(counts.identities, 0)
            self.assertEqual(counts.mismatches, 0)
            with self.assertRaises(StopIteration):
                next(alignments)

    def test_2228_tblastx_001(self):
        path = "Blast/tab_2228_tblastx_001.txt"
        with open(path) as stream:
            alignments = Align.parse(stream, "tabular")
            self.assertEqual(alignments.metadata["Program"], "TBLASTX")
            self.assertEqual(alignments.metadata["Version"], "2.2.28+")
            self.assertEqual(alignments.metadata["RID"], "P06P5RN0015")
            self.assertEqual(alignments.metadata["Database"], "refseq_rna")
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISH
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISH

gi|296147        60 SLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K 116
                 60 |||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116
gi|296147        60 SLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 1)
            self.assertEqual(alignment.query.annotations["end"], 349)
            self.assertEqual(alignment.target.annotations["start"], 1)
            self.assertEqual(alignment.target.annotations["end"], 349)
            self.assertEqual(
                alignment.target.seq,
                "WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K",
            )
            self.assertEqual(
                alignment.query.seq,
                "WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-76, places=76)
            self.assertAlmostEqual(alignment.annotations["bit score"], 289)
            self.assertAlmostEqual(alignment.score, 626)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 116)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 116)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 626.0; 116 aligned letters; 116 identities; 0 mismatches; 116 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 626.0,
    aligned = 116:
        identities = 116,
        positives = 116,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 116)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 116)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALPGSSF*HSLIGKPTRKGVRNP
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALPGSSF*HSLIGKPTRKGVRNP

gi|296147        60 DVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP 116
                 60 |||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116
gi|296147        60 DVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[0, 116],
                              [0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 349)
            self.assertEqual(alignment.query.annotations["end"], 1)
            self.assertEqual(alignment.target.annotations["start"], 349)
            self.assertEqual(alignment.target.annotations["end"], 1)
            self.assertEqual(
                alignment.target.seq,
                "LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALPGSSF*HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP",
            )
            self.assertEqual(
                alignment.query.seq,
                "LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALPGSSF*HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-73, places=73)
            self.assertAlmostEqual(alignment.annotations["bit score"], 278)
            self.assertAlmostEqual(alignment.score, 602)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 116)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 116)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-3")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 602.0; 116 aligned letters; 116 identities; 0 mismatches; 116 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 602.0,
    aligned = 116:
        identities = 116,
        positives = 116,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 116)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 116)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIR
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIR

gi|296147        60 MSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH 116
                 60 |||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116
gi|296147        60 MSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 348)
            self.assertEqual(alignment.query.annotations["end"], 0)
            self.assertEqual(alignment.target.annotations["start"], 348)
            self.assertEqual(alignment.target.annotations["end"], 0)
            self.assertEqual(
                alignment.target.seq,
                "F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH",
            )
            self.assertEqual(
                alignment.query.seq,
                "F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-72, places=72)
            self.assertAlmostEqual(alignment.annotations["bit score"], 274)
            self.assertAlmostEqual(alignment.score, 593)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 116)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 116)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 593.0; 116 aligned letters; 116 identities; 0 mismatches; 116 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 593.0,
    aligned = 116:
        identities = 116,
        positives = 116,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 116)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 116)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 GHEHWRV*LHAKAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRT
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 GHEHWRV*LHAKAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRT

gi|296147        60 PFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS 116
                 60 |||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116
gi|296147        60 PFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 2)
            self.assertEqual(alignment.query.annotations["end"], 350)
            self.assertEqual(alignment.target.annotations["start"], 2)
            self.assertEqual(alignment.target.annotations["end"], 350)
            self.assertEqual(
                alignment.target.seq,
                "GHEHWRV*LHAKAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS",
            )
            self.assertEqual(
                alignment.query.seq,
                "GHEHWRV*LHAKAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-70, places=70)
            self.assertAlmostEqual(alignment.annotations["bit score"], 270)
            self.assertAlmostEqual(alignment.score, 583)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 116)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 116)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "3/3")
            self.assertEqual(alignment.query.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 583.0; 116 aligned letters; 116 identities; 0 mismatches; 116 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 583.0,
    aligned = 116:
        identities = 116,
        positives = 116,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 116)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 116)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKS
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKS

gi|296147        60 GCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA 116
                 60 |||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116
gi|296147        60 GCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 2)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 2)
            self.assertEqual(
                alignment.target.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKSGCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKSGCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-58, places=58)
            self.assertAlmostEqual(alignment.annotations["bit score"], 229)
            self.assertAlmostEqual(alignment.score, 495)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 116)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 116)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 586.0; 116 aligned letters; 116 identities; 0 mismatches; 116 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 586.0,
    aligned = 116:
        identities = 116,
        positives = 116,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 116)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 116)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI
                  0 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI

gi|296147        60 PRSRLSEILDAFIEATHLAMEIQLK 85
                 60 ||||||||||||||||||||||||| 85
gi|296147        60 PRSRLSEILDAFIEATHLAMEIQLK 85
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  85],
                              [  0,  85]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 93)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-53, places=53)
            self.assertAlmostEqual(alignment.annotations["bit score"], 197)
            self.assertAlmostEqual(alignment.score, 425)
            self.assertEqual(alignment.shape, (2, 85))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 85)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 85)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 73)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 425.0; 85 aligned letters; 85 identities; 0 mismatches; 85 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 425.0,
    aligned = 85:
        identities = 85,
        positives = 85,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 85)
            self.assertEqual(counts.identities, 85)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 85)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296147         0 MAMNTGGFDSMQRQ 14
                  0 |||||||||||||| 14
gi|296147         0 MAMNTGGFDSMQRQ 14
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 14],
                              [ 0, 14]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296147483|ref|NM_001183135.1|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|296147483|ref|NM_001183135.1|;gi|116616412|gb|EF059095.1|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "296147483")
            self.assertEqual(alignment.target.annotations["gis"], "296147483;116616412")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001183135")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_001183135;EF059095"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001183135.1")
            self.assertEqual(alignment.target.annotations["length"], 4911)
            self.assertEqual(alignment.query.annotations["start"], 0)
            self.assertEqual(alignment.query.annotations["end"], 42)
            self.assertEqual(alignment.target.annotations["start"], 0)
            self.assertEqual(alignment.target.annotations["end"], 42)
            self.assertEqual(alignment.target.seq, "MAMNTGGFDSMQRQ")
            self.assertEqual(alignment.query.seq, "MAMNTGGFDSMQRQ")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-53, places=53)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.3)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 14))
            self.assertAlmostEqual(alignment.annotations["% identity"], 100.00)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 0)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 100.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "32630;559292")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A;N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Saccharomyces cerevisiae S288c Mon2p (MON2), mRNA<>Synthetic construct Saccharomyces cerevisiae clone FLH203015.01X MON2, complete sequence",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 12)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 73.0; 14 aligned letters; 14 identities; 0 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 73.0,
    aligned = 14:
        identities = 14,
        positives = 14,
        mismatches = 0.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 14)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 0)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 TIKHASDKSIDILKTIQNIEELVRHPDFVTPLVLACSSRNAKLTSIAMQCLQGLASVPSI
                  0 ||.|||||||.|||.....|||.|||||..|.||||.|||||.|..||||||||..||||
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI

gi|365982        60 PESRIPEVLDGFIEATQLAMEIQLK 85
                 60 |.||..|.||.|||||.|||||||| 85
gi|296147        60 PRSRLSEILDAFIEATHLAMEIQLK 85
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  85],
                              [  0,  85]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 93)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 87)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "TIKHASDKSIDILKTIQNIEELVRHPDFVTPLVLACSSRNAKLTSIAMQCLQGLASVPSIPESRIPEVLDGFIEATQLAMEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-37, places=37)
            self.assertAlmostEqual(alignment.annotations["bit score"], 152)
            self.assertAlmostEqual(alignment.score, 327)
            self.assertEqual(alignment.shape, (2, 85))
            self.assertAlmostEqual(alignment.annotations["% identity"], 72.94)
            self.assertEqual(alignment.annotations["identical"], 62)
            self.assertEqual(alignment.annotations["mismatches"], 23)
            self.assertEqual(alignment.annotations["positives"], 73)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 85.88)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 73)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 327.0; 85 aligned letters; 62 identities; 23 mismatches; 73 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 327.0,
    aligned = 85:
        identities = 62,
        positives = 73,
        mismatches = 23.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 85)
            self.assertEqual(counts.identities, 62)
            self.assertEqual(counts.mismatches, 23)
            self.assertEqual(counts.positives, 73)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 FRI*KKKFNH*TC* 14
                  0 |||.||||||..|| 14
gi|296147         0 FRIEKKKFNHSPC* 14
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 14],
                              [ 0, 14]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 68)
            self.assertEqual(alignment.query.annotations["end"], 110)
            self.assertEqual(alignment.target.annotations["start"], 62)
            self.assertEqual(alignment.target.annotations["end"], 104)
            self.assertEqual(alignment.target.seq, "FRI*KKKFNH*TC*")
            self.assertEqual(alignment.query.seq, "FRIEKKKFNHSPC*")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-37, places=37)
            self.assertAlmostEqual(alignment.annotations["bit score"], 26.3)
            self.assertAlmostEqual(alignment.score, 51)
            self.assertEqual(alignment.shape, (2, 14))
            self.assertAlmostEqual(alignment.annotations["% identity"], 78.57)
            self.assertEqual(alignment.annotations["identical"], 11)
            self.assertEqual(alignment.annotations["mismatches"], 3)
            self.assertEqual(alignment.annotations["positives"], 11)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 78.57)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "3/3")
            self.assertEqual(alignment.query.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 12)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 51.0; 14 aligned letters; 11 identities; 3 mismatches; 11 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 51.0,
    aligned = 14:
        identities = 11,
        positives = 11,
        mismatches = 3.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 14)
            self.assertEqual(counts.identities, 11)
            self.assertEqual(counts.mismatches, 3)
            self.assertEqual(counts.positives, 11)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 TFNCISIAS*VASMNPSRTSGILDSGIEGTDANPCRHCMAIEVNLAFLDEQARTK 55
                  0 |||.||||.|||||..|..|.....||.||...|||||.|..|.|||||.||.|| 55
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 185)
            self.assertEqual(alignment.target.annotations["start"], 344)
            self.assertEqual(alignment.target.annotations["end"], 179)
            self.assertEqual(
                alignment.target.seq,
                "TFNCISIAS*VASMNPSRTSGILDSGIEGTDANPCRHCMAIEVNLAFLDEQARTK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6e-20, places=20)
            self.assertAlmostEqual(alignment.annotations["bit score"], 68.0)
            self.assertAlmostEqual(alignment.score, 142)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 61.82)
            self.assertEqual(alignment.annotations["identical"], 34)
            self.assertEqual(alignment.annotations["mismatches"], 21)
            self.assertEqual(alignment.annotations["positives"], 38)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 69.09)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 142.0; 55 aligned letters; 34 identities; 21 mismatches; 38 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 142.0,
    aligned = 55:
        identities = 34,
        positives = 38,
        mismatches = 21.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 34)
            self.assertEqual(counts.mismatches, 21)
            self.assertEqual(counts.positives, 38)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 VFRISIDLSLACLMVEFLLLDSEERECNSWSNCFRKEVN 39
                  0 .|.||.|||||..||||||.|||..|.||.|.|...|.| 39
gi|296147         0 LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESN 39
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  39],
                              [  0,  39]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 137)
            self.assertEqual(alignment.query.annotations["end"], 20)
            self.assertEqual(alignment.target.annotations["start"], 131)
            self.assertEqual(alignment.target.annotations["end"], 14)
            self.assertEqual(
                alignment.target.seq, "VFRISIDLSLACLMVEFLLLDSEERECNSWSNCFRKEVN"
            )
            self.assertEqual(
                alignment.query.seq, "LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESN"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6e-20, places=20)
            self.assertAlmostEqual(alignment.annotations["bit score"], 52.8)
            self.assertAlmostEqual(alignment.score, 109)
            self.assertEqual(alignment.shape, (2, 39))
            self.assertAlmostEqual(alignment.annotations["% identity"], 61.54)
            self.assertEqual(alignment.annotations["identical"], 24)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.36)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 33)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 109.0; 39 aligned letters; 24 identities; 15 mismatches; 29 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 109.0,
    aligned = 39:
        identities = 24,
        positives = 29,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 39)
            self.assertEqual(counts.identities, 24)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 NWTRNYTPFLQNLKEEIQPLNMLATNQSIF*RLFKI*KNL*GTLILLHLWSWPVHREMPN
                  0 |...|....|.|.||||||..||..|....|.............|...|..|.....|..
gi|296147         0 NLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSLSCWLANQGMLK

gi|365982        60 *LQLPCNAYKDWRPYLQYQSQESQKF*TDSLKPLS*RWRYN*K 103
                 60 |....||||.|..|..........||...||..|..|||.||| 103
gi|296147        60 *RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K 103
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 103],
                              [  0, 103]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 40)
            self.assertEqual(alignment.query.annotations["end"], 349)
            self.assertEqual(alignment.target.annotations["start"], 34)
            self.assertEqual(alignment.target.annotations["end"], 343)
            self.assertEqual(
                alignment.target.seq,
                "NWTRNYTPFLQNLKEEIQPLNMLATNQSIF*RLFKI*KNL*GTLILLHLWSWPVHREMPN*LQLPCNAYKDWRPYLQYQSQESQKF*TDSLKPLS*RWRYN*K",
            )
            self.assertEqual(
                alignment.query.seq,
                "NLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 9e-08, places=8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 61.1)
            self.assertAlmostEqual(alignment.score, 127)
            self.assertEqual(alignment.shape, (2, 103))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.95)
            self.assertEqual(alignment.annotations["identical"], 36)
            self.assertEqual(alignment.annotations["mismatches"], 67)
            self.assertEqual(alignment.annotations["positives"], 52)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.49)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 88)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 127.0; 103 aligned letters; 36 identities; 67 mismatches; 52 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 127.0,
    aligned = 103:
        identities = 36,
        positives = 52,
        mismatches = 67.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 103)
            self.assertEqual(counts.identities, 36)
            self.assertEqual(counts.mismatches, 67)
            self.assertEqual(counts.positives, 52)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|365982         0 GRQSL*ALHGN*S*FGISR*TGQDQRCNKIRVPYKFFYILNSL*NID*FVASMFNG*ISS
                  0 |.|||||||.....|.|.....|..|...||..........|......|..||.||||||
gi|296147         0 G*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISS

gi|365982        60 FRF*R 65
                 60 |||.| 65
gi|296147        60 FRFGR 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|365982352|ref|XM_003667962.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|365982352|ref|XM_003667962.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "365982352")
            self.assertEqual(alignment.target.annotations["gis"], "365982352")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003667962")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003667962.1")
            self.assertEqual(alignment.target.annotations["length"], 4932)
            self.assertEqual(alignment.query.annotations["start"], 261)
            self.assertEqual(alignment.query.annotations["end"], 66)
            self.assertEqual(alignment.target.annotations["start"], 255)
            self.assertEqual(alignment.target.annotations["end"], 60)
            self.assertEqual(
                alignment.target.seq,
                "GRQSL*ALHGN*S*FGISR*TGQDQRCNKIRVPYKFFYILNSL*NID*FVASMFNG*ISSFRF*R",
            )
            self.assertEqual(
                alignment.query.seq,
                "G*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.029)
            self.assertAlmostEqual(alignment.annotations["bit score"], 42.8)
            self.assertAlmostEqual(alignment.score, 87)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 36)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.38)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071378")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 87.0; 65 aligned letters; 28 identities; 37 mismatches; 36 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 87.0,
    aligned = 65:
        identities = 28,
        positives = 36,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 36)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366988         0 SIKHASDKSIEILKTIQNIEDLASHPDFVTPLVESCLSRNAKLTSIAMQCLQGLASAPSI
                  0 .|.|||||||||||.....|.|..||||..|.|..|.|||||.|..||||||||...|||
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI

gi|366988        60 PESRLSGVLDGFIEATHLAIEIQLK 85
                 60 |.||||..||.||||||||.||||| 85
gi|296147        60 PRSRLSEILDAFIEATHLAMEIQLK 85
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  85],
                              [  0,  85]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366988334|ref|XM_003673886.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366988334|ref|XM_003673886.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366988334")
            self.assertEqual(alignment.target.annotations["gis"], "366988334")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003673886.1")
            self.assertEqual(alignment.target.annotations["length"], 4938)
            self.assertEqual(alignment.query.annotations["start"], 93)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "SIKHASDKSIEILKTIQNIEDLASHPDFVTPLVESCLSRNAKLTSIAMQCLQGLASAPSIPESRLSGVLDGFIEATHLAIEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-32, places=32)
            self.assertAlmostEqual(alignment.annotations["bit score"], 143)
            self.assertAlmostEqual(alignment.score, 306)
            self.assertEqual(alignment.shape, (2, 85))
            self.assertAlmostEqual(alignment.annotations["% identity"], 68.24)
            self.assertEqual(alignment.annotations["identical"], 58)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 71)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 83.53)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1064592")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 73)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 306.0; 85 aligned letters; 58 identities; 27 mismatches; 71 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 306.0,
    aligned = 85:
        identities = 58,
        positives = 71,
        mismatches = 27.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 85)
            self.assertEqual(counts.identities, 58)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 71)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366988         0 TFSCISIARCVASINPSRTPDSLLSGMDGADAKPCKHCIAIEVNLAFLDRHDST 54
                  0 ||..|||||.|||...|...||.|.|.||....||.||||..|.|||||....| 54
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANT 54
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  54],
                              [  0,  54]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366988334|ref|XM_003673886.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366988334|ref|XM_003673886.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366988334")
            self.assertEqual(alignment.target.annotations["gis"], "366988334")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003673886.1")
            self.assertEqual(alignment.target.annotations["length"], 4938)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 188)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 188)
            self.assertEqual(
                alignment.target.seq,
                "TFSCISIARCVASINPSRTPDSLLSGMDGADAKPCKHCIAIEVNLAFLDRHDST",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANT",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-16, places=16)
            self.assertAlmostEqual(alignment.annotations["bit score"], 62.5)
            self.assertAlmostEqual(alignment.score, 130)
            self.assertEqual(alignment.shape, (2, 54))
            self.assertAlmostEqual(alignment.annotations["% identity"], 55.56)
            self.assertEqual(alignment.annotations["identical"], 30)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 36)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1064592")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 46)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 130.0; 54 aligned letters; 30 identities; 24 mismatches; 36 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 130.0,
    aligned = 54:
        identities = 30,
        positives = 36,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 54)
            self.assertEqual(counts.identities, 30)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 36)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366988         0 VFKISIDLSLACLIEVFLLLDSEDNECNSRSNC 33
                  0 .|.||.|||||.....|||.||||.|.||.|.| 33
gi|296147         0 LFNISMDLSLAWRMVEFLLFDSEDKERNSASSC 33
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  33],
                              [  0,  33]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366988334|ref|XM_003673886.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366988334|ref|XM_003673886.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366988334")
            self.assertEqual(alignment.target.annotations["gis"], "366988334")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003673886.1")
            self.assertEqual(alignment.target.annotations["length"], 4938)
            self.assertEqual(alignment.query.annotations["start"], 137)
            self.assertEqual(alignment.query.annotations["end"], 38)
            self.assertEqual(alignment.target.annotations["start"], 137)
            self.assertEqual(alignment.target.annotations["end"], 38)
            self.assertEqual(alignment.target.seq, "VFKISIDLSLACLIEVFLLLDSEDNECNSRSNC")
            self.assertEqual(alignment.query.seq, "LFNISMDLSLAWRMVEFLLFDSEDKERNSASSC")
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-16, places=16)
            self.assertAlmostEqual(alignment.annotations["bit score"], 44.6)
            self.assertAlmostEqual(alignment.score, 91)
            self.assertEqual(alignment.shape, (2, 33))
            self.assertAlmostEqual(alignment.annotations["% identity"], 60.61)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 24)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 72.73)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1064592")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 28)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 91.0; 33 aligned letters; 20 identities; 13 mismatches; 24 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 91.0,
    aligned = 33:
        identities = 20,
        positives = 24,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 33)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 24)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366988         0 *LYFNCKMCRFYKSIENSR*SAFRYGWCRC*AL*TLHSNRGQLSVP**T*FYQWSDKIRM
                  0 ||.....|......|.|.|..|.|..|.....||.||......|.||..........|||
gi|296147         0 *LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRM

gi|366988        60 ACQIFNVLDSF*DLDRLVTCMLDRSVPSFRFGRQ*MQF*VQLFLKGLKTCSLNSH 115
                 60 .........||..|....|.|......||||||...||...|.|.|.|..|...| 115
gi|296147        60 SF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH 115
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 115],
                              [  0, 115]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366988334|ref|XM_003673886.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366988334|ref|XM_003673886.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366988334")
            self.assertEqual(alignment.target.annotations["gis"], "366988334")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003673886")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003673886.1")
            self.assertEqual(alignment.target.annotations["length"], 4938)
            self.assertEqual(alignment.query.annotations["start"], 345)
            self.assertEqual(alignment.query.annotations["end"], 0)
            self.assertEqual(alignment.target.annotations["start"], 345)
            self.assertEqual(alignment.target.annotations["end"], 0)
            self.assertEqual(
                alignment.target.seq,
                "*LYFNCKMCRFYKSIENSR*SAFRYGWCRC*AL*TLHSNRGQLSVP**T*FYQWSDKIRMACQIFNVLDSF*DLDRLVTCMLDRSVPSFRFGRQ*MQF*VQLFLKGLKTCSLNSH",
            )
            self.assertEqual(
                alignment.query.seq,
                "*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 54.2)
            self.assertAlmostEqual(alignment.score, 112)
            self.assertEqual(alignment.shape, (2, 115))
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.04)
            self.assertEqual(alignment.annotations["identical"], 38)
            self.assertEqual(alignment.annotations["mismatches"], 77)
            self.assertEqual(alignment.annotations["positives"], 58)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.43)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1064592")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Naumovozyma castellii CBS 4309 hypothetical protein (NCAS0A09950) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 112.0; 115 aligned letters; 38 identities; 77 mismatches; 58 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 112.0,
    aligned = 115:
        identities = 38,
        positives = 58,
        mismatches = 77.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 115)
            self.assertEqual(counts.identities, 38)
            self.assertEqual(counts.mismatches, 77)
            self.assertEqual(counts.positives, 58)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|255710         0 VRHASDKSIEILKTVHEFEDLPRHPDFVTPFVLSCASKNAKLTSVSVQCLQKMSSVNCIP
                  0 .||||||||||||.||.||.|.|||||..||||.|.|.|||.|....||||..|.|..||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|255710        60 EDRIEDVLDAFIDSTHLAAEIQLK 84
                 60 ..|....|||||..||||.||||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|255710474|ref|XM_002551475.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|255710474|ref|XM_002551475.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "255710474")
            self.assertEqual(alignment.target.annotations["gis"], "255710474")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002551475")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002551475")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002551475.1")
            self.assertEqual(alignment.target.annotations["length"], 4845)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "VRHASDKSIEILKTVHEFEDLPRHPDFVTPFVLSCASKNAKLTSVSVQCLQKMSSVNCIPEDRIEDVLDAFIDSTHLAAEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-32, places=32)
            self.assertAlmostEqual(alignment.annotations["bit score"], 141)
            self.assertAlmostEqual(alignment.score, 303)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.48)
            self.assertEqual(alignment.annotations["identical"], 55)
            self.assertEqual(alignment.annotations["mismatches"], 29)
            self.assertEqual(alignment.annotations["positives"], 71)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 84.52)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559295")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Lachancea thermotolerans CBS 6340 KLTH0A01342p (KLTH0A01342g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Lachancea thermotolerans CBS 6340 KLTH0A01342p (KLTH0A01342g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 73)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 303.0; 84 aligned letters; 55 identities; 29 mismatches; 71 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 303.0,
    aligned = 84:
        identities = 55,
        positives = 71,
        mismatches = 29.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 55)
            self.assertEqual(counts.mismatches, 29)
            self.assertEqual(counts.positives, 71)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|255710         0 TLSCISAARWVESMNASSTSSILSSGMQLTDDIFCRHCTETLVSLAFLEAHERTK 55
                  0 |...||.||.|.||.||..|.....|...|.|..||||....|.||||.....|| 55
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|255710474|ref|XM_002551475.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|255710474|ref|XM_002551475.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "255710474")
            self.assertEqual(alignment.target.annotations["gis"], "255710474")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002551475")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002551475")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002551475.1")
            self.assertEqual(alignment.target.annotations["length"], 4845)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 185)
            self.assertEqual(alignment.target.annotations["start"], 347)
            self.assertEqual(alignment.target.annotations["end"], 182)
            self.assertEqual(
                alignment.target.seq,
                "TLSCISAARWVESMNASSTSSILSSGMQLTDDIFCRHCTETLVSLAFLEAHERTK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 45.45)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 30)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.73)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "559295")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Lachancea thermotolerans CBS 6340 KLTH0A01342p (KLTH0A01342g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Lachancea thermotolerans CBS 6340 KLTH0A01342p (KLTH0A01342g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 73)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 55 aligned letters; 25 identities; 30 mismatches; 29 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 55:
        identities = 25,
        positives = 29,
        mismatches = 30.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 30)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|254579         0 IRNASDKSIEILKVVHSYEELSRHPDFIVPLVMSCASKNAKLTTISMQCFQKLATVPCIP
                  0 ||.||||||||||.|||.|||.|||||..|.|..|.|.|||.||..|||.|.|.|||.||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|254579        60 VDKLSDVLDAFIEANQLAMDIKLK 84
                 60 ...||..|||||||..|||.|.|| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|254579534|ref|XM_002495708.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|254579534|ref|XM_002495708.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "254579534")
            self.assertEqual(alignment.target.annotations["gis"], "254579534")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002495708.1")
            self.assertEqual(alignment.target.annotations["length"], 4866)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 96)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "IRNASDKSIEILKVVHSYEELSRHPDFIVPLVMSCASKNAKLTTISMQCFQKLATVPCIPVDKLSDVLDAFIEANQLAMDIKLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6e-32, places=32)
            self.assertAlmostEqual(alignment.annotations["bit score"], 141)
            self.assertAlmostEqual(alignment.score, 302)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 67.86)
            self.assertEqual(alignment.annotations["identical"], 57)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 72)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 85.71)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559307")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 302.0; 84 aligned letters; 57 identities; 27 mismatches; 72 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 302.0,
    aligned = 84:
        identities = 57,
        positives = 72,
        mismatches = 27.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 57)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 72)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|254579         0 TFSFISIASWLASINASSTSESLSTGIHGTVANFWKHCIDIVVNLAFLD 49
                  0 ||..||||...||..||..|.|...||.|||.....|||..||.||||| 49
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLD 49
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  49],
                              [  0,  49]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|254579534|ref|XM_002495708.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|254579534|ref|XM_002495708.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "254579534")
            self.assertEqual(alignment.target.annotations["gis"], "254579534")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002495708.1")
            self.assertEqual(alignment.target.annotations["length"], 4866)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 203)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 203)
            self.assertEqual(
                alignment.target.seq,
                "TFSFISIASWLASINASSTSESLSTGIHGTVANFWKHCIDIVVNLAFLD",
            )
            self.assertEqual(
                alignment.query.seq, "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLD"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 51.0)
            self.assertAlmostEqual(alignment.score, 105)
            self.assertEqual(alignment.shape, (2, 49))
            self.assertAlmostEqual(alignment.annotations["% identity"], 55.10)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 33)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.35)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "559307")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 42)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 105.0; 49 aligned letters; 27 identities; 22 mismatches; 33 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 105.0,
    aligned = 49:
        identities = 27,
        positives = 33,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 49)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 33)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|254579         0 TTFKISIDLSLAFLIAVFLFFDSDESECNSELSSFQKLPNSP 42
                  0 |.|.||.|||||.....||.|||...|.||..|......|.| 42
gi|296147         0 TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPP 42
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  42],
                              [  0,  42]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|254579534|ref|XM_002495708.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|254579534|ref|XM_002495708.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "254579534")
            self.assertEqual(alignment.target.annotations["gis"], "254579534")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002495708.1")
            self.assertEqual(alignment.target.annotations["length"], 4866)
            self.assertEqual(alignment.query.annotations["start"], 140)
            self.assertEqual(alignment.query.annotations["end"], 14)
            self.assertEqual(alignment.target.annotations["start"], 140)
            self.assertEqual(alignment.target.annotations["end"], 14)
            self.assertEqual(
                alignment.target.seq, "TTFKISIDLSLAFLIAVFLFFDSDESECNSELSSFQKLPNSP"
            )
            self.assertEqual(
                alignment.query.seq, "TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPP"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 41.8)
            self.assertAlmostEqual(alignment.score, 85)
            self.assertEqual(alignment.shape, (2, 42))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.62)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 25)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 59.52)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "559307")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 36)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 85.0; 42 aligned letters; 20 identities; 22 mismatches; 25 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 85.0,
    aligned = 42:
        identities = 20,
        positives = 25,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 42)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 25)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|254579         0 RVAFTFIRVEEKEYCY*EC*R*IN*NFESSSQL*GIIKTSRFYSTASDVMCIQECQIDYY
                  0 |.||...|.|.|......||.||.|..|.|...||..|||.|.........|.||..|..
gi|296147         0 RIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDP

gi|254579        60 INAMFPKIGHSAMYTGR*TLRRT*CVYRGQPAGNGYKTK 99
                 60 .|||.........|..........|...|.....|...| 99
gi|296147        60 GNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIK 99
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  99],
                              [  0,  99]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|254579534|ref|XM_002495708.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|254579534|ref|XM_002495708.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "254579534")
            self.assertEqual(alignment.target.annotations["gis"], "254579534")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002495708")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002495708.1")
            self.assertEqual(alignment.target.annotations["length"], 4866)
            self.assertEqual(alignment.query.annotations["start"], 50)
            self.assertEqual(alignment.query.annotations["end"], 347)
            self.assertEqual(alignment.target.annotations["start"], 50)
            self.assertEqual(alignment.target.annotations["end"], 347)
            self.assertEqual(
                alignment.target.seq,
                "RVAFTFIRVEEKEYCY*EC*R*IN*NFESSSQL*GIIKTSRFYSTASDVMCIQECQIDYYINAMFPKIGHSAMYTGR*TLRRT*CVYRGQPAGNGYKTK",
            )
            self.assertEqual(
                alignment.query.seq,
                "RIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 99))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.31)
            self.assertEqual(alignment.annotations["identical"], 31)
            self.assertEqual(alignment.annotations["mismatches"], 68)
            self.assertEqual(alignment.annotations["positives"], 53)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 53.54)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "3/3")
            self.assertEqual(alignment.query.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "559307")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Zygosaccharomyces rouxii hypothetical protein (ZYRO0C02266g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 85)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 99 aligned letters; 31 identities; 68 mismatches; 53 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 99:
        identities = 31,
        positives = 53,
        mismatches = 68.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 99)
            self.assertEqual(counts.identities, 31)
            self.assertEqual(counts.mismatches, 68)
            self.assertEqual(counts.positives, 53)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 VKHASDKSIEILKTVTNINDLTRHPDFVVPFILACSSGNAKLTSISMQCIQVISTVQCIP
                  0 ..|||||||||||.|.....|.|||||..||.|||.|.|||.|...|||.|..|||..||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|156843        60 STRISEILDAFINATHLAVEIQLK 84
                 60 ..|.||||||||.|||||.||||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 96)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "VKHASDKSIEILKTVTNINDLTRHPDFVVPFILACSSGNAKLTSISMQCIQVISTVQCIPSTRISEILDAFINATHLAVEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-31, places=31)
            self.assertAlmostEqual(alignment.annotations["bit score"], 139)
            self.assertAlmostEqual(alignment.score, 299)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 66.67)
            self.assertEqual(alignment.annotations["identical"], 56)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["positives"], 71)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 84.52)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 299.0; 84 aligned letters; 56 identities; 28 mismatches; 71 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 299.0,
    aligned = 84:
        identities = 56,
        positives = 71,
        mismatches = 28.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 56)
            self.assertEqual(counts.mismatches, 28)
            self.assertEqual(counts.positives, 71)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 WQLNLLILQPLKSN*LQTYNLYLLNRKEKVQMLNTLVINLLKF*KL*LI*MI*QDIQIS*
                  0 |...|..|.|.|.|..|...|||.||||..|....||||.|..||.......|.||.||.
gi|296147         0 WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISH

gi|156843        60 YHSFWHVLQEMQS*LQFLCNAFKLYQLYNVYQVLEFLKF*MLLLMLLI*RWKYN*K 116
                 60 ..|.|...|.|..|....|||....|..........|||.|..|.|||.||..||| 116
gi|296147        60 SLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 1)
            self.assertEqual(alignment.query.annotations["end"], 349)
            self.assertEqual(alignment.target.annotations["start"], 1)
            self.assertEqual(alignment.target.annotations["end"], 349)
            self.assertEqual(
                alignment.target.seq,
                "WQLNLLILQPLKSN*LQTYNLYLLNRKEKVQMLNTLVINLLKF*KL*LI*MI*QDIQIS*YHSFWHVLQEMQS*LQFLCNAFKLYQLYNVYQVLEFLKF*MLLLMLLI*RWKYN*K",
            )
            self.assertEqual(
                alignment.query.seq,
                "WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSLSCWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-14, places=14)
            self.assertAlmostEqual(alignment.annotations["bit score"], 81.3)
            self.assertAlmostEqual(alignment.score, 171)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 42.24)
            self.assertEqual(alignment.annotations["identical"], 49)
            self.assertEqual(alignment.annotations["mismatches"], 67)
            self.assertEqual(alignment.annotations["positives"], 66)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 56.90)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 171.0; 116 aligned letters; 49 identities; 67 mismatches; 66 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 171.0,
    aligned = 116:
        identities = 49,
        positives = 66,
        mismatches = 67.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 49)
            self.assertEqual(counts.mismatches, 67)
            self.assertEqual(counts.positives, 66)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 F*LYFHR*MSSINKSI*NFRNSSTWYTLYS*YNLNALHRN*S*LCIS*RTCQNEWYYEIW
                  0 |||..||.|||.|..|.|||..........|..|.|||.......|.|...|.|...||.
gi|296147         0 F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIR

gi|156843        60 MSC*IIYISYSFQNFNRFITSVFNICTFSFRFRR*RL*VCSQLLFKGCKIKRFNCH 116
                 60 ||.|.....||||..|.||||..|....||||.|||...|..|...|.|......| 116
gi|296147        60 MSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH 116
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 116],
                              [  0, 116]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 348)
            self.assertEqual(alignment.query.annotations["end"], 0)
            self.assertEqual(alignment.target.annotations["start"], 348)
            self.assertEqual(alignment.target.annotations["end"], 0)
            self.assertEqual(
                alignment.target.seq,
                "F*LYFHR*MSSINKSI*NFRNSSTWYTLYS*YNLNALHRN*S*LCIS*RTCQNEWYYEIWMSC*IIYISYSFQNFNRFITSVFNICTFSFRFRR*RL*VCSQLLFKGCKIKRFNCH",
            )
            self.assertEqual(
                alignment.query.seq,
                "F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLPLHGVKPSSVHGH",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 72.1)
            self.assertAlmostEqual(alignment.score, 151)
            self.assertEqual(alignment.shape, (2, 116))
            self.assertAlmostEqual(alignment.annotations["% identity"], 42.24)
            self.assertEqual(alignment.annotations["identical"], 49)
            self.assertEqual(alignment.annotations["mismatches"], 67)
            self.assertEqual(alignment.annotations["positives"], 60)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.72)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 99)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 151.0; 116 aligned letters; 49 identities; 67 mismatches; 60 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 151.0,
    aligned = 116:
        identities = 49,
        positives = 60,
        mismatches = 67.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 116)
            self.assertEqual(counts.identities, 49)
            self.assertEqual(counts.mismatches, 67)
            self.assertEqual(counts.positives, 60)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 TFNCISTAK*VALIKASKISEILVLGIHCTVDIT*MHCIEIEVSFAF 47
                  0 |||.||.|.|||..||||||.....||..|||....|||...|..|| 47
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAF 47
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  47],
                              [  0,  47]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 209)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 209)
            self.assertEqual(
                alignment.target.seq, "TFNCISTAK*VALIKASKISEILVLGIHCTVDIT*MHCIEIEVSFAF"
            )
            self.assertEqual(
                alignment.query.seq, "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAF"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 47.3)
            self.assertAlmostEqual(alignment.score, 97)
            self.assertEqual(alignment.shape, (2, 47))
            self.assertAlmostEqual(alignment.annotations["% identity"], 55.32)
            self.assertEqual(alignment.annotations["identical"], 26)
            self.assertEqual(alignment.annotations["mismatches"], 21)
            self.assertEqual(alignment.annotations["positives"], 30)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.83)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 40)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 97.0; 47 aligned letters; 26 identities; 21 mismatches; 30 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 97.0,
    aligned = 47:
        identities = 26,
        positives = 30,
        mismatches = 21.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 47)
            self.assertEqual(counts.identities, 26)
            self.assertEqual(counts.mismatches, 21)
            self.assertEqual(counts.positives, 30)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 HFLKNMPK*MVLRNLDVLLNHLY*LQFSKFQ*IYH*RV*HLYFFFSIQKIKIVSL*SIAF
                  0 |.|...|.....||.||.|.......||..|.||||....|.|||||.|||...|...||
gi|296147         0 HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAF

gi|156843        60 
                 60 
gi|296147        60 
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  60],
                              [  0,  60]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 214)
            self.assertEqual(alignment.query.annotations["end"], 34)
            self.assertEqual(alignment.target.annotations["start"], 214)
            self.assertEqual(alignment.target.annotations["end"], 34)
            self.assertEqual(
                alignment.target.seq,
                "HFLKNMPK*MVLRNLDVLLNHLY*LQFSKFQ*IYH*RV*HLYFFFSIQKIKIVSL*SIAF",
            )
            self.assertEqual(
                alignment.query.seq,
                "HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAF",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.5)
            self.assertAlmostEqual(alignment.score, 82)
            self.assertEqual(alignment.shape, (2, 60))
            self.assertAlmostEqual(alignment.annotations["% identity"], 45.00)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 33)
            self.assertEqual(alignment.annotations["positives"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-3")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 51)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 82.0; 60 aligned letters; 27 identities; 33 mismatches; 31 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 82.0,
    aligned = 60:
        identities = 27,
        positives = 31,
        mismatches = 33.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 60)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 33)
            self.assertEqual(counts.positives, 31)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 KAIDYRLTIFIF*IEKKKYRC*TR***IY*NFENCN*YK*FNKTSRFRSTIHFGMFFRKC
                  0 ||...|...|||.|||||......||||.|..|...|.....|||.||.....|.....|
gi|296147         0 KAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC

gi|156843        60 KANFNFYAMHSSYINCTMYTKY*NF*NFRCFY*CYSFSGGNTIKS 105
                 60 .......||.....|...|......|||.|..|.||...|..||| 105
gi|296147        60 *NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS 105
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 105],
                              [  0, 105]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 35)
            self.assertEqual(alignment.query.annotations["end"], 350)
            self.assertEqual(alignment.target.annotations["start"], 35)
            self.assertEqual(alignment.target.annotations["end"], 350)
            self.assertEqual(
                alignment.target.seq,
                "KAIDYRLTIFIF*IEKKKYRC*TR***IY*NFENCN*YK*FNKTSRFRSTIHFGMFFRKCKANFNFYAMHSSYINCTMYTKY*NF*NFRCFY*CYSFSGGNTIKS",
            )
            self.assertEqual(
                alignment.query.seq,
                "KAT*SRIAFFIFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMPTGTVNRSIYSSKPAV*NFGCLH*GYSSRDGDSIKS",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-08, places=8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 62.5)
            self.assertAlmostEqual(alignment.score, 130)
            self.assertEqual(alignment.shape, (2, 105))
            self.assertAlmostEqual(alignment.annotations["% identity"], 38.10)
            self.assertEqual(alignment.annotations["identical"], 40)
            self.assertEqual(alignment.annotations["mismatches"], 65)
            self.assertEqual(alignment.annotations["positives"], 58)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.24)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "3/3")
            self.assertEqual(alignment.query.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 90)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 130.0; 105 aligned letters; 40 identities; 65 mismatches; 58 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 130.0,
    aligned = 105:
        identities = 40,
        positives = 58,
        mismatches = 65.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 105)
            self.assertEqual(counts.identities, 40)
            self.assertEqual(counts.mismatches, 65)
            self.assertEqual(counts.positives, 58)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156843         0 TVFKISIDLSLACLTSVLFLFDSEDKDCKSVVNC 34
                  0 |.|.||.|||||.......|||||||...|...| 34
gi|296147         0 TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSC 34
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  34],
                              [  0,  34]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156843402|ref|XM_001644719.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156843402|ref|XM_001644719.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156843402")
            self.assertEqual(alignment.target.annotations["gis"], "156843402")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001644719")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001644719.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 140)
            self.assertEqual(alignment.query.annotations["end"], 38)
            self.assertEqual(alignment.target.annotations["start"], 140)
            self.assertEqual(alignment.target.annotations["end"], 38)
            self.assertEqual(alignment.target.seq, "TVFKISIDLSLACLTSVLFLFDSEDKDCKSVVNC")
            self.assertEqual(alignment.query.seq, "TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSC")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.19)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.0)
            self.assertAlmostEqual(alignment.score, 81)
            self.assertEqual(alignment.shape, (2, 34))
            self.assertAlmostEqual(alignment.annotations["% identity"], 52.94)
            self.assertEqual(alignment.annotations["identical"], 18)
            self.assertEqual(alignment.annotations["mismatches"], 16)
            self.assertEqual(alignment.annotations["positives"], 22)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.71)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "436907")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Vanderwaltozyma polyspora DSM 70294 hypothetical protein (Kpol_1020p19) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 100)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 29)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 81.0; 34 aligned letters; 18 identities; 16 mismatches; 22 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 81.0,
    aligned = 34:
        identities = 18,
        positives = 22,
        mismatches = 16.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 34)
            self.assertEqual(counts.identities, 18)
            self.assertEqual(counts.mismatches, 16)
            self.assertEqual(counts.positives, 22)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410075         0 VKHASEKSLKILKTVHDSGDFLRHPDFVVPFVLACSSRSAKLTTIGLQGLQNLSSTNCIP
                  0 ..|||.||..|||.||......|||||..||||||.||.||.||...|.||.||....||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|410075        60 KDRLIEVLDGFIDATHLAMEIQLK 84
                 60 ..||.|.||.||.||||||||||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410075642|ref|XM_003955355.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410075642|ref|XM_003955355.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410075642")
            self.assertEqual(alignment.target.annotations["gis"], "410075642")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003955355")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003955355")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003955355.1")
            self.assertEqual(alignment.target.annotations["length"], 4881)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 96)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "VKHASEKSLKILKTVHDSGDFLRHPDFVVPFVLACSSRSAKLTTIGLQGLQNLSSTNCIPKDRLIEVLDGFIDATHLAMEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-28, places=28)
            self.assertAlmostEqual(alignment.annotations["bit score"], 129)
            self.assertAlmostEqual(alignment.score, 276)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 61.90)
            self.assertEqual(alignment.annotations["identical"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 32)
            self.assertEqual(alignment.annotations["positives"], 67)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 79.76)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071382")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Kazachstania africana CBS 2517 hypothetical protein (KAFR0A08350), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Kazachstania africana CBS 2517 hypothetical protein (KAFR0A08350), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 276.0; 84 aligned letters; 52 identities; 32 mismatches; 67 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 276.0,
    aligned = 84:
        identities = 52,
        positives = 67,
        mismatches = 32.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 52)
            self.assertEqual(counts.mismatches, 32)
            self.assertEqual(counts.positives, 67)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410075         0 TFS*ISIAKCVASINPSNTSINRSLGIQLVDDKFCKP*RPIVVNLALRDEQAKTNGTTKS
                  0 ||.|||||..|||...|..|..|..||....|..|......||.||..|.||.|.|..||
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKS

gi|410075        60 GCLRKSPLSCTVFKILRDFSLACLTSEFLLLASDDKE*SPVSSCL 105
                 60 |||..|...||.|.|..|.|||....||||..|.|||....|||| 105
gi|296147        60 GCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL 105
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 105],
                              [  0, 105]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410075642|ref|XM_003955355.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410075642|ref|XM_003955355.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410075642")
            self.assertEqual(alignment.target.annotations["gis"], "410075642")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003955355")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003955355")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003955355.1")
            self.assertEqual(alignment.target.annotations["length"], 4881)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 35)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 35)
            self.assertEqual(
                alignment.target.seq,
                "TFS*ISIAKCVASINPSNTSINRSLGIQLVDDKFCKP*RPIVVNLALRDEQAKTNGTTKSGCLRKSPLSCTVFKILRDFSLACLTSEFLLLASDDKE*SPVSSCL",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKSGCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 67.5)
            self.assertAlmostEqual(alignment.score, 141)
            self.assertEqual(alignment.shape, (2, 105))
            self.assertAlmostEqual(alignment.annotations["% identity"], 49.52)
            self.assertEqual(alignment.annotations["identical"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 53)
            self.assertEqual(alignment.annotations["positives"], 61)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.10)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071382")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Kazachstania africana CBS 2517 hypothetical protein (KAFR0A08350), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Kazachstania africana CBS 2517 hypothetical protein (KAFR0A08350), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 90)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 198.0; 105 aligned letters; 52 identities; 53 mismatches; 61 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 198.0,
    aligned = 105:
        identities = 52,
        positives = 61,
        mismatches = 53.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 105)
            self.assertEqual(counts.identities, 52)
            self.assertEqual(counts.mismatches, 53)
            self.assertEqual(counts.positives, 61)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470736         0 VKHASDRSLQILRIVHSFEELERHPDFILPFVLSCKSGNAKFTSLSMQSLQRLAIHQSIP
                  0 ..||||.|..||..|||||||||||||.|||||.|.|.|||.|.|.||.||.|....|||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|470736        60 REQIEHVLEALIDSTQLAVEIQLK 84
                 60 |......|.|.|..|.||.||||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|47073627|ref|NM_210010.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|47073627|ref|NM_210010.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "47073627")
            self.assertEqual(alignment.target.annotations["gis"], "47073627")
            self.assertEqual(alignment.target.annotations["acc."], "NM_210010")
            self.assertEqual(alignment.target.annotations["accs."], "NM_210010")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_210010.1")
            self.assertEqual(alignment.target.annotations["length"], 4776)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "VKHASDRSLQILRIVHSFEELERHPDFILPFVLSCKSGNAKFTSLSMQSLQRLAIHQSIPREQIEHVLEALIDSTQLAVEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-28, places=28)
            self.assertAlmostEqual(alignment.annotations["bit score"], 129)
            self.assertAlmostEqual(alignment.score, 276)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 61.90)
            self.assertEqual(alignment.annotations["identical"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 32)
            self.assertEqual(alignment.annotations["positives"], 70)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 83.33)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284811")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 276.0; 84 aligned letters; 52 identities; 32 mismatches; 70 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 276.0,
    aligned = 84:
        identities = 52,
        positives = 70,
        mismatches = 32.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 52)
            self.assertEqual(counts.mismatches, 32)
            self.assertEqual(counts.positives, 70)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470736         0 TFS*ISTASCVESISASSTCSICSRGIDWWIARRCRLCIDSEVNFAFPDLHERTNGRIKS
                  0 ||.|||.|..|.|..||.......||||......||.||...|..||.|....|.|..||
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKS

gi|470736        60 GCRSSSSKLWTIRNICNERSLACFTSELRRLDSEARACRSCVSCLTVLVN 110
                 60 ||.||||||.|..||....|||....|....|||.....|..|||....| 110
gi|296147        60 GCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESN 110
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 110],
                              [  0, 110]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|47073627|ref|NM_210010.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|47073627|ref|NM_210010.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "47073627")
            self.assertEqual(alignment.target.annotations["gis"], "47073627")
            self.assertEqual(alignment.target.annotations["acc."], "NM_210010")
            self.assertEqual(alignment.target.annotations["accs."], "NM_210010")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_210010.1")
            self.assertEqual(alignment.target.annotations["length"], 4776)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 20)
            self.assertEqual(alignment.target.annotations["start"], 347)
            self.assertEqual(alignment.target.annotations["end"], 17)
            self.assertEqual(
                alignment.target.seq,
                "TFS*ISTASCVESISASSTCSICSRGIDWWIARRCRLCIDSEVNFAFPDLHERTNGRIKSGCRSSSSKLWTIRNICNERSLACFTSELRRLDSEARACRSCVSCLTVLVN",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTKGSAKSGCLSSSSKLCTLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESN",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 52.4)
            self.assertAlmostEqual(alignment.score, 108)
            self.assertEqual(alignment.shape, (2, 110))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.55)
            self.assertEqual(alignment.annotations["identical"], 49)
            self.assertEqual(alignment.annotations["mismatches"], 61)
            self.assertEqual(alignment.annotations["positives"], 56)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.91)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "284811")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 94)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 172.0; 110 aligned letters; 49 identities; 61 mismatches; 56 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 172.0,
    aligned = 110:
        identities = 49,
        positives = 56,
        mismatches = 61.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 110)
            self.assertEqual(counts.identities, 49)
            self.assertEqual(counts.mismatches, 61)
            self.assertEqual(counts.positives, 56)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470736         0 F*LNLNGQLCGINQCFEYMFYLLPWNRLVDSQTLQTLH*QRSKLRIS*LT*EDERKNKVW
                  0 |||||.......|............||....|.|..||.|.....|.||....||.....
gi|296147         0 F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIR

gi|470736        60 VSF*FFKTMDYPQYL*RAIACMFHFRITSLRFRS*GVQILCQLP 104
                 60 .|||..|||...|||...|..|....|.|.||..|..|....|| 104
gi|296147        60 MSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLP 104
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0, 104],
                              [  0, 104]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|47073627|ref|NM_210010.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|47073627|ref|NM_210010.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "47073627")
            self.assertEqual(alignment.target.annotations["gis"], "47073627")
            self.assertEqual(alignment.target.annotations["acc."], "NM_210010")
            self.assertEqual(alignment.target.annotations["accs."], "NM_210010")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_210010.1")
            self.assertEqual(alignment.target.annotations["length"], 4776)
            self.assertEqual(alignment.query.annotations["start"], 348)
            self.assertEqual(alignment.query.annotations["end"], 36)
            self.assertEqual(alignment.target.annotations["start"], 345)
            self.assertEqual(alignment.target.annotations["end"], 33)
            self.assertEqual(
                alignment.target.seq,
                "F*LNLNGQLCGINQCFEYMFYLLPWNRLVDSQTLQTLH*QRSKLRIS*LT*EDERKNKVWVSF*FFKTMDYPQYL*RAIACMFHFRITSLRFRS*GVQILCQLP",
            )
            self.assertEqual(
                alignment.query.seq,
                "F*LNLHREMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKLP",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 50.1)
            self.assertAlmostEqual(alignment.score, 103)
            self.assertEqual(alignment.shape, (2, 104))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.58)
            self.assertEqual(alignment.annotations["identical"], 37)
            self.assertEqual(alignment.annotations["mismatches"], 67)
            self.assertEqual(alignment.annotations["positives"], 52)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284811")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ashbya gossypii ATCC 10895 AEL204Cp (AGOS_AEL204C) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 94)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 89)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 103.0; 104 aligned letters; 37 identities; 67 mismatches; 52 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 103.0,
    aligned = 104:
        identities = 37,
        positives = 52,
        mismatches = 67.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 104)
            self.assertEqual(counts.identities, 37)
            self.assertEqual(counts.mismatches, 67)
            self.assertEqual(counts.positives, 52)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|502941         0 VKEASHKSIEILKTIKTINDLENHPDFVVPFALACKTKNAKMTTIAMQCLQNMASTRCIP
                  0 ...||.|||||||.......||.||||..||.|||...||||||.||||||.......||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|502941        60 EKRMDMILDAFIEATQLAMDIQLK 84
                 60 ..|...|||||||||.|||.|||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50294190|ref|XM_449507.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50294190|ref|XM_449507.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50294190")
            self.assertEqual(alignment.target.annotations["gis"], "50294190")
            self.assertEqual(alignment.target.annotations["acc."], "XM_449507")
            self.assertEqual(alignment.target.annotations["accs."], "XM_449507")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_449507.1")
            self.assertEqual(alignment.target.annotations["length"], 4980)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 183)
            self.assertEqual(alignment.target.annotations["end"], 435)
            self.assertEqual(
                alignment.target.seq,
                "VKEASHKSIEILKTIKTINDLENHPDFVVPFALACKTKNAKMTTIAMQCLQNMASTRCIPEKRMDMILDAFIEATQLAMDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-28, places=28)
            self.assertAlmostEqual(alignment.annotations["bit score"], 128)
            self.assertAlmostEqual(alignment.score, 274)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 60.71)
            self.assertEqual(alignment.annotations["identical"], 51)
            self.assertEqual(alignment.annotations["mismatches"], 33)
            self.assertEqual(alignment.annotations["positives"], 66)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 78.57)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284593")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 274.0; 84 aligned letters; 51 identities; 33 mismatches; 66 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 274.0,
    aligned = 84:
        identities = 51,
        positives = 66,
        mismatches = 33.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 51)
            self.assertEqual(counts.mismatches, 33)
            self.assertEqual(counts.positives, 66)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|502941         0 TFNCISMASCVASINASNIISILFSGIHLVEAMFCRHCIAIVVILAFL 48
                  0 |||.||.|..|||..||.|......||.......||||||.||||||| 48
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFL 48
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  48],
                              [  0,  48]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50294190|ref|XM_449507.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50294190|ref|XM_449507.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50294190")
            self.assertEqual(alignment.target.annotations["gis"], "50294190")
            self.assertEqual(alignment.target.annotations["acc."], "XM_449507")
            self.assertEqual(alignment.target.annotations["accs."], "XM_449507")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_449507.1")
            self.assertEqual(alignment.target.annotations["length"], 4980)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 206)
            self.assertEqual(alignment.target.annotations["start"], 437)
            self.assertEqual(alignment.target.annotations["end"], 293)
            self.assertEqual(
                alignment.target.seq, "TFNCISMASCVASINASNIISILFSGIHLVEAMFCRHCIAIVVILAFL"
            )
            self.assertEqual(
                alignment.query.seq, "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 49.2)
            self.assertAlmostEqual(alignment.score, 101)
            self.assertEqual(alignment.shape, (2, 48))
            self.assertAlmostEqual(alignment.annotations["% identity"], 56.25)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 21)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.42)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "284593")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 41)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 101.0; 48 aligned letters; 27 identities; 21 mismatches; 29 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 101.0,
    aligned = 48:
        identities = 27,
        positives = 29,
        mismatches = 21.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 48)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 21)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|502941         0 VFNISIDLWLASLTSELRLRASATSA*RSASNCL 34
                  0 .||||.||.||....|..|..|......|||.|| 34
gi|296147         0 LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL 34
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  34],
                              [  0,  34]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50294190|ref|XM_449507.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50294190|ref|XM_449507.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50294190")
            self.assertEqual(alignment.target.annotations["gis"], "50294190")
            self.assertEqual(alignment.target.annotations["acc."], "XM_449507")
            self.assertEqual(alignment.target.annotations["accs."], "XM_449507")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_449507.1")
            self.assertEqual(alignment.target.annotations["length"], 4980)
            self.assertEqual(alignment.query.annotations["start"], 137)
            self.assertEqual(alignment.query.annotations["end"], 35)
            self.assertEqual(alignment.target.annotations["start"], 224)
            self.assertEqual(alignment.target.annotations["end"], 122)
            self.assertEqual(alignment.target.seq, "VFNISIDLWLASLTSELRLRASATSA*RSASNCL")
            self.assertEqual(alignment.query.seq, "LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 27.6)
            self.assertAlmostEqual(alignment.score, 54)
            self.assertEqual(alignment.shape, (2, 34))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.06)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 18)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.88)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "284593")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida glabrata CBS 138 hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 29)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 54.0; 34 aligned letters; 16 identities; 18 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 54.0,
    aligned = 34:
        identities = 16,
        positives = 19,
        mismatches = 18.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 34)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 18)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|444314         0 VKHTSDKALEILKTCHSNLDLKRHPDFIIPLIKACSSKSAKLTTIAMQCLQRMSSVDCIP
                  0 ..|.|||..||||..||...|.|||||..|...||.|..||.||.||||||..|.|..||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|444314        60 DSRISQVLDSFIEATLLASDIQLK 84
                 60 .||.|..||.|||||.||..|||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|444314872|ref|XM_004178046.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|444314872|ref|XM_004178046.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "444314872")
            self.assertEqual(alignment.target.annotations["gis"], "444314872")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004178046.1")
            self.assertEqual(alignment.target.annotations["length"], 5190)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 99)
            self.assertEqual(alignment.target.annotations["end"], 351)
            self.assertEqual(
                alignment.target.seq,
                "VKHTSDKALEILKTCHSNLDLKRHPDFIIPLIKACSSKSAKLTTIAMQCLQRMSSVDCIPDSRISQVLDSFIEATLLASDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-27, places=27)
            self.assertAlmostEqual(alignment.annotations["bit score"], 127)
            self.assertAlmostEqual(alignment.score, 271)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 59.52)
            self.assertEqual(alignment.annotations["identical"], 50)
            self.assertEqual(alignment.annotations["mismatches"], 34)
            self.assertEqual(alignment.annotations["positives"], 69)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 82.14)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071380")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 82)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 271.0; 84 aligned letters; 50 identities; 34 mismatches; 69 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 271.0,
    aligned = 84:
        identities = 50,
        positives = 69,
        mismatches = 34.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 50)
            self.assertEqual(counts.mismatches, 34)
            self.assertEqual(counts.positives, 69)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|444314         0 TFS*ISEANRVASMKESNT*DILESGIQSTDDILCKHCIAIVVNLALFELHAFIK 55
                  0 ||.|||.|..|||||.|...|....||..|.|..|.||||.||.||.....|..| 55
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|444314872|ref|XM_004178046.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|444314872|ref|XM_004178046.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "444314872")
            self.assertEqual(alignment.target.annotations["gis"], "444314872")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004178046.1")
            self.assertEqual(alignment.target.annotations["length"], 5190)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 185)
            self.assertEqual(alignment.target.annotations["start"], 353)
            self.assertEqual(alignment.target.annotations["end"], 188)
            self.assertEqual(
                alignment.target.seq,
                "TFS*ISEANRVASMKESNT*DILESGIQSTDDILCKHCIAIVVNLALFELHAFIK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 48.7)
            self.assertAlmostEqual(alignment.score, 100)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 50.91)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 56.36)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071380")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 82)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 100.0; 55 aligned letters; 28 identities; 27 mismatches; 31 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 100.0,
    aligned = 55:
        identities = 28,
        positives = 31,
        mismatches = 27.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 31)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|444314         0 VLRISKALSLVCLTSEFFLLDSETK 25
                  0 ...||..|||.....||.|.|||.| 25
gi|296147         0 LFNISMDLSLAWRMVEFLLFDSEDK 25
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  25],
                              [  0,  25]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|444314872|ref|XM_004178046.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|444314872|ref|XM_004178046.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "444314872")
            self.assertEqual(alignment.target.annotations["gis"], "444314872")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004178046.1")
            self.assertEqual(alignment.target.annotations["length"], 5190)
            self.assertEqual(alignment.query.annotations["start"], 137)
            self.assertEqual(alignment.query.annotations["end"], 62)
            self.assertEqual(alignment.target.annotations["start"], 140)
            self.assertEqual(alignment.target.annotations["end"], 65)
            self.assertEqual(alignment.target.seq, "VLRISKALSLVCLTSEFFLLDSETK")
            self.assertEqual(alignment.query.seq, "LFNISMDLSLAWRMVEFLLFDSEDK")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 23.5)
            self.assertAlmostEqual(alignment.score, 45)
            self.assertEqual(alignment.shape, (2, 25))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.00)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 13)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071380")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 82)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 21)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 45.0; 25 aligned letters; 12 identities; 13 mismatches; 13 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 45.0,
    aligned = 25:
        identities = 12,
        positives = 13,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 25)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 13)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|444314         0 SL*ALHCDSSQFGTLRTTCFYQRYYEIRVTF*IQIAMACLKDLQSFITCMFNF*IFSSGF
                  0 |||||||....|..........|..|||..||....|.....|..|||.|.|.||.|..|
gi|296147         0 SL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRF

gi|444314        60 
                 60 
gi|296147        60 
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  60],
                              [  0,  60]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|444314872|ref|XM_004178046.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|444314872|ref|XM_004178046.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "444314872")
            self.assertEqual(alignment.target.annotations["gis"], "444314872")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004178046")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004178046.1")
            self.assertEqual(alignment.target.annotations["length"], 5190)
            self.assertEqual(alignment.query.annotations["start"], 252)
            self.assertEqual(alignment.query.annotations["end"], 72)
            self.assertEqual(alignment.target.annotations["start"], 255)
            self.assertEqual(alignment.target.annotations["end"], 75)
            self.assertEqual(
                alignment.target.seq,
                "SL*ALHCDSSQFGTLRTTCFYQRYYEIRVTF*IQIAMACLKDLQSFITCMFNF*IFSSGF",
            )
            self.assertEqual(
                alignment.query.seq,
                "SL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRF",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.075)
            self.assertAlmostEqual(alignment.annotations["bit score"], 41.4)
            self.assertAlmostEqual(alignment.score, 84)
            self.assertEqual(alignment.shape, (2, 60))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.67)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 31)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071380")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora blattae CBS 6284 hypothetical protein (TBLA0A07860) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 82)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 51)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 84.0; 60 aligned letters; 25 identities; 35 mismatches; 31 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 84.0,
    aligned = 60:
        identities = 25,
        positives = 31,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 60)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 31)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 VKHASDKSLQILRIVHSFQELERHPDFVHPFVLSCKSGNAKFTTLSMQCLQRLAIHRSIS
                  0 ..||||||..||..||||.||||||||..||||.|.|.|||.|||.|||||.|....||.
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|363751        60 KEQIEPVLEALIDSTQLAVEIQLK 84
                 60 .......|.|.|..|.||.||||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "VKHASDKSLQILRIVHSFQELERHPDFVHPFVLSCKSGNAKFTTLSMQCLQRLAIHRSISKEQIEPVLEALIDSTQLAVEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-27, places=27)
            self.assertAlmostEqual(alignment.annotations["bit score"], 127)
            self.assertAlmostEqual(alignment.score, 271)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 60.71)
            self.assertEqual(alignment.annotations["identical"], 51)
            self.assertEqual(alignment.annotations["mismatches"], 33)
            self.assertEqual(alignment.annotations["positives"], 69)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 82.14)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 271.0; 84 aligned letters; 51 identities; 33 mismatches; 69 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 271.0,
    aligned = 84:
        identities = 51,
        positives = 69,
        mismatches = 33.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 51)
            self.assertEqual(counts.mismatches, 33)
            self.assertEqual(counts.positives, 69)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 TFNWISTAN*VESINASKTGSICSLEIDLWIANRCKHCIERVVNLAFPDLHDNTK 55
                  0 |||.||.|.||.|..|||........||......|.|||.|||.|||.|...||| 55
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 185)
            self.assertEqual(alignment.target.annotations["start"], 347)
            self.assertEqual(alignment.target.annotations["end"], 182)
            self.assertEqual(
                alignment.target.seq,
                "TFNWISTAN*VESINASKTGSICSLEIDLWIANRCKHCIERVVNLAFPDLHDNTK",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQANTK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-08, places=8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 52.4)
            self.assertAlmostEqual(alignment.score, 108)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 50.91)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 32)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.18)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 108.0; 55 aligned letters; 28 identities; 27 mismatches; 32 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 108.0,
    aligned = 55:
        identities = 28,
        positives = 32,
        mismatches = 27.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 32)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 TILKI*SDLSDACLTSEFLLLDSED 25
                  0 |...|..|||.|....||||.|||| 25
gi|296147         0 TLFNISMDLSLAWRMVEFLLFDSED 25
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  25],
                              [  0,  25]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 140)
            self.assertEqual(alignment.query.annotations["end"], 65)
            self.assertEqual(alignment.target.annotations["start"], 137)
            self.assertEqual(alignment.target.annotations["end"], 62)
            self.assertEqual(alignment.target.seq, "TILKI*SDLSDACLTSEFLLLDSED")
            self.assertEqual(alignment.query.seq, "TLFNISMDLSLAWRMVEFLLFDSED")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-08, places=8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 27.2)
            self.assertAlmostEqual(alignment.score, 53)
            self.assertEqual(alignment.shape, (2, 25))
            self.assertAlmostEqual(alignment.annotations["% identity"], 56.00)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 11)
            self.assertEqual(alignment.annotations["positives"], 15)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 21)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 53.0; 25 aligned letters; 14 identities; 11 mismatches; 15 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 53.0,
    aligned = 25:
        identities = 14,
        positives = 15,
        mismatches = 11.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 25)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 11)
            self.assertEqual(counts.positives, 15)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 QSLQTLHRKSSKFSIS*FT**YKRVYKIGMSFQFLKTMNYS*DLKRFIRCMFNLRISSFG
                  0 |||..||.....|||.|......|...|.|||..||||.....|..||..|.|..||||.
gi|296147         0 QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFR

gi|363751        60 FRRQRIQILIQL 72
                 60 |.|.|.|....| 72
gi|296147        60 FGR*RTQFCFKL 72
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  72],
                              [  0,  72]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 255)
            self.assertEqual(alignment.query.annotations["end"], 39)
            self.assertEqual(alignment.target.annotations["start"], 252)
            self.assertEqual(alignment.target.annotations["end"], 36)
            self.assertEqual(
                alignment.target.seq,
                "QSLQTLHRKSSKFSIS*FT**YKRVYKIGMSFQFLKTMNYS*DLKRFIRCMFNLRISSFGFRRQRIQILIQL",
            )
            self.assertEqual(
                alignment.query.seq,
                "QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQFCFKL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 72))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 32)
            self.assertEqual(alignment.annotations["mismatches"], 40)
            self.assertEqual(alignment.annotations["positives"], 37)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.39)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 62)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 72 aligned letters; 32 identities; 40 mismatches; 37 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 72:
        identities = 32,
        positives = 37,
        mismatches = 40.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 72)
            self.assertEqual(counts.identities, 32)
            self.assertEqual(counts.mismatches, 40)
            self.assertEqual(counts.positives, 37)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 *HFLIYMIIQKGVQNRDVVPIPENYELFLRFEAIYQMHV*PQNFFFWIQK 50
                  0 ||.||.....|||.|.||...|.||.||.....||..|....||||.|.| 50
gi|296147         0 *HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRK 50
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  50],
                              [  0,  50]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 217)
            self.assertEqual(alignment.query.annotations["end"], 67)
            self.assertEqual(alignment.target.annotations["start"], 214)
            self.assertEqual(alignment.target.annotations["end"], 64)
            self.assertEqual(
                alignment.target.seq,
                "*HFLIYMIIQKGVQNRDVVPIPENYELFLRFEAIYQMHV*PQNFFFWIQK",
            )
            self.assertEqual(
                alignment.query.seq,
                "*HSLIGKPTRKGVRNPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.021)
            self.assertAlmostEqual(alignment.annotations["bit score"], 43.2)
            self.assertAlmostEqual(alignment.score, 88)
            self.assertEqual(alignment.shape, (2, 50))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.00)
            self.assertEqual(alignment.annotations["identical"], 24)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-3")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 43)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 88.0; 50 aligned letters; 24 identities; 26 mismatches; 29 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 88.0,
    aligned = 50:
        identities = 24,
        positives = 29,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 50)
            self.assertEqual(counts.identities, 24)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363751         0 VF*IQKKKF*G*TCI**IASNLKNSS*FSGIGTTSRFCTPFCIIM*IRKC*IYYSFYAMF
                  0 .|.|.||||....|.|||......|.||.|...||.|.|||.....|..||......||.
gi|296147         0 IFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMP

gi|363751        60 AAIGNPQIY 69
                 60 ....|..|| 69
gi|296147        60 TGTVNRSIY 69
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  69],
                              [  0,  69]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363751207|ref|XM_003645773.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363751207|ref|XM_003645773.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363751207")
            self.assertEqual(alignment.target.annotations["gis"], "363751207")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003645773")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003645773.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 65)
            self.assertEqual(alignment.query.annotations["end"], 272)
            self.assertEqual(alignment.target.annotations["start"], 62)
            self.assertEqual(alignment.target.annotations["end"], 269)
            self.assertEqual(
                alignment.target.seq,
                "VF*IQKKKF*G*TCI**IASNLKNSS*FSGIGTTSRFCTPFCIIM*IRKC*IYYSFYAMFAAIGNPQIY",
            )
            self.assertEqual(
                alignment.query.seq,
                "IFRIEKKKFNHSPC***IH*DIEKST*F*GARKTSGFRTPFRVGLPIKEC*NDDPGNAMPTGTVNRSIY",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.27)
            self.assertAlmostEqual(alignment.annotations["bit score"], 39.6)
            self.assertAlmostEqual(alignment.score, 80)
            self.assertEqual(alignment.shape, (2, 69))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.58)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 41)
            self.assertEqual(alignment.annotations["positives"], 38)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "3/3")
            self.assertEqual(alignment.query.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "931890")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Eremothecium cymbalariae DBVPG#7215 hypothetical protein (Ecym_3526) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 89)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 59)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 80.0; 69 aligned letters; 28 identities; 41 mismatches; 38 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 80.0,
    aligned = 69:
        identities = 28,
        positives = 38,
        mismatches = 41.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 69)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 41)
            self.assertEqual(counts.positives, 38)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366997         0 IHQASDKSIEILKTVKSIDELRRHPDFILPFIIATSSGNAKLTSIALQCIQRFLTVEYIP
                  0 |..||||||||||.|.|..||.|||||.|||..|..|.|||.|..|.||.|...||..||
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|366997        60 KSQLGALLDSFISATHLADEIKLK 84
                 60 .|.|...||.||.|||||.||.|| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366997674|ref|XM_003683526.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366997674|ref|XM_003683526.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366997674")
            self.assertEqual(alignment.target.annotations["gis"], "366997674")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003683526.1")
            self.assertEqual(alignment.target.annotations["length"], 4890)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 99)
            self.assertEqual(alignment.target.annotations["end"], 351)
            self.assertEqual(
                alignment.target.seq,
                "IHQASDKSIEILKTVKSIDELRRHPDFILPFIIATSSGNAKLTSIALQCIQRFLTVEYIPKSQLGALLDSFISATHLADEIKLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-26, places=26)
            self.assertAlmostEqual(alignment.annotations["bit score"], 123)
            self.assertAlmostEqual(alignment.score, 263)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 61.90)
            self.assertEqual(alignment.annotations["identical"], 52)
            self.assertEqual(alignment.annotations["mismatches"], 32)
            self.assertEqual(alignment.annotations["positives"], 65)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 77.38)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071381")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 263.0; 84 aligned letters; 52 identities; 32 mismatches; 65 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 263.0,
    aligned = 84:
        identities = 52,
        positives = 65,
        mismatches = 32.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 52)
            self.assertEqual(counts.mismatches, 32)
            self.assertEqual(counts.positives, 65)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366997         0 NQDVFSIHQLT*LFSKFQWTYH*LDESHCLFFLIRLIKDPSLIIVIF*KPRRLQ 54
                  0 |.|||...|...|||..||.|||..|....||.||.||...|..|.|.....|| 54
gi|296147         0 NPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQ 54
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  54],
                              [  0,  54]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366997674|ref|XM_003683526.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366997674|ref|XM_003683526.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366997674")
            self.assertEqual(alignment.target.annotations["gis"], "366997674")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003683526.1")
            self.assertEqual(alignment.target.annotations["length"], 4890)
            self.assertEqual(alignment.query.annotations["start"], 175)
            self.assertEqual(alignment.query.annotations["end"], 13)
            self.assertEqual(alignment.target.annotations["start"], 178)
            self.assertEqual(alignment.target.annotations["end"], 16)
            self.assertEqual(
                alignment.target.seq,
                "NQDVFSIHQLT*LFSKFQWTYH*LDESHCLFFLIRLIKDPSLIIVIF*KPRRLQ",
            )
            self.assertEqual(
                alignment.query.seq,
                "NPDVFLAPQNYVLFSISQWIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQ",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.0)
            self.assertAlmostEqual(alignment.score, 81)
            self.assertEqual(alignment.shape, (2, 54))
            self.assertAlmostEqual(alignment.annotations["% identity"], 46.30)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 29)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.85)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-3")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071381")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 46)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 81.0; 54 aligned letters; 25 identities; 29 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 81.0,
    aligned = 54:
        identities = 25,
        positives = 28,
        mismatches = 29.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 54)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 29)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366997         0 TFNFISSAKWVAEIKESSKAPN*LLGIYSTVKNLCIHCKAILVNFA 46
                  0 |||.||.|..||..|.|......|.||..||...|.||.|..|..| 46
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILA 46
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  46],
                              [  0,  46]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366997674|ref|XM_003683526.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366997674|ref|XM_003683526.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366997674")
            self.assertEqual(alignment.target.annotations["gis"], "366997674")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003683526.1")
            self.assertEqual(alignment.target.annotations["length"], 4890)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 212)
            self.assertEqual(alignment.target.annotations["start"], 353)
            self.assertEqual(alignment.target.annotations["end"], 215)
            self.assertEqual(
                alignment.target.seq, "TFNFISSAKWVAEIKESSKAPN*LLGIYSTVKNLCIHCKAILVNFA"
            )
            self.assertEqual(
                alignment.query.seq, "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILA"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 46))
            self.assertAlmostEqual(alignment.annotations["% identity"], 45.65)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 25)
            self.assertEqual(alignment.annotations["positives"], 27)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.70)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071381")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 39)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 46 aligned letters; 21 identities; 25 mismatches; 27 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 46:
        identities = 21,
        positives = 27,
        mismatches = 25.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 46)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 25)
            self.assertEqual(counts.positives, 27)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366997         0 QMGS*NKRV*QSAQLTLRNIFNS*KSLYTLQSNTC*FCITRRGSNYKWQYKIRMSSQFIN
                  0 .|.|.|.......|...||..|.|.||..|......|.|....|.......||||.....
gi|296147         0 EMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLK

gi|366997        60 *LNCFQNFNGLITSLMNLIVSSF*FV**KTQ 91
                 60 ....||..||.|||..|...|||.|..|.|| 91
gi|296147        60 TMYSFQYLNGFITSMANG*ISSFRFGR*RTQ 91
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  91],
                              [  0,  91]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366997674|ref|XM_003683526.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366997674|ref|XM_003683526.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366997674")
            self.assertEqual(alignment.target.annotations["gis"], "366997674")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003683526.1")
            self.assertEqual(alignment.target.annotations["length"], 4890)
            self.assertEqual(alignment.query.annotations["start"], 327)
            self.assertEqual(alignment.query.annotations["end"], 54)
            self.assertEqual(alignment.target.annotations["start"], 330)
            self.assertEqual(alignment.target.annotations["end"], 57)
            self.assertEqual(
                alignment.target.seq,
                "QMGS*NKRV*QSAQLTLRNIFNS*KSLYTLQSNTC*FCITRRGSNYKWQYKIRMSSQFIN*LNCFQNFNGLITSLMNLIVSSF*FV**KTQ",
            )
            self.assertEqual(
                alignment.query.seq,
                "EMSSLNEGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LASQHERECEIRMSF*LLKTMYSFQYLNGFITSMANG*ISSFRFGR*RTQ",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.001)
            self.assertAlmostEqual(alignment.annotations["bit score"], 47.3)
            self.assertAlmostEqual(alignment.score, 97)
            self.assertEqual(alignment.shape, (2, 91))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.26)
            self.assertEqual(alignment.annotations["identical"], 33)
            self.assertEqual(alignment.annotations["mismatches"], 58)
            self.assertEqual(alignment.annotations["positives"], 47)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 51.65)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071381")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 78)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 97.0; 91 aligned letters; 33 identities; 58 mismatches; 47 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 97.0,
    aligned = 91:
        identities = 33,
        positives = 47,
        mismatches = 58.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 91)
            self.assertEqual(counts.identities, 33)
            self.assertEqual(counts.mismatches, 58)
            self.assertEqual(counts.positives, 47)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|366997         0 QTWVFYQTNQKEETMRFIKLVISPLKF*KQLSQLMN*EDILI 42
                  0 |..|.|..|.|||...|..|||.||..||....|..|.||.| 42
gi|296147         0 QNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRI 42
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 42],
                              [ 0, 42]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|366997674|ref|XM_003683526.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|366997674|ref|XM_003683526.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "366997674")
            self.assertEqual(alignment.target.annotations["gis"], "366997674")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003683526")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003683526.1")
            self.assertEqual(alignment.target.annotations["length"], 4890)
            self.assertEqual(alignment.query.annotations["start"], 49)
            self.assertEqual(alignment.query.annotations["end"], 175)
            self.assertEqual(alignment.target.annotations["start"], 52)
            self.assertEqual(alignment.target.annotations["end"], 178)
            self.assertEqual(
                alignment.target.seq, "QTWVFYQTNQKEETMRFIKLVISPLKF*KQLSQLMN*EDILI"
            )
            self.assertEqual(
                alignment.query.seq, "QNCVLYLPNRKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRI"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.075)
            self.assertAlmostEqual(alignment.annotations["bit score"], 41.4)
            self.assertAlmostEqual(alignment.score, 84)
            self.assertEqual(alignment.shape, (2, 42))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.62)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 27)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.29)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "1071381")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tetrapisispora phaffii CBS 4417 hypothetical protein (TPHA0A00550) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 96)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 36)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 84.0; 42 aligned letters; 20 identities; 22 mismatches; 27 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 84.0,
    aligned = 42:
        identities = 20,
        positives = 27,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 42)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 27)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|367014         0 IKQASDKSIEILRTVRNYEELSNRSEFLAPFLMSCSSKNAKLTSISMQCLQRLSSTPSLS
                  0 |..|||||||||..|...|||.....|..||...|.|.|||.|...|||||.||..||..
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|367014        60 KDKLSDVLEAFIVATQLALDMKLK 84
                 60 ...||..|.|||.||.||....|| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|367014048|ref|XM_003681476.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|367014048|ref|XM_003681476.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "367014048")
            self.assertEqual(alignment.target.annotations["gis"], "367014048")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003681476.1")
            self.assertEqual(alignment.target.annotations["length"], 4902)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 96)
            self.assertEqual(alignment.target.annotations["end"], 348)
            self.assertEqual(
                alignment.target.seq,
                "IKQASDKSIEILRTVRNYEELSNRSEFLAPFLMSCSSKNAKLTSISMQCLQRLSSTPSLSKDKLSDVLEAFIVATQLALDMKLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-24, places=24)
            self.assertAlmostEqual(alignment.annotations["bit score"], 115)
            self.assertAlmostEqual(alignment.score, 246)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 52.38)
            self.assertEqual(alignment.annotations["identical"], 44)
            self.assertEqual(alignment.annotations["mismatches"], 40)
            self.assertEqual(alignment.annotations["positives"], 68)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 80.95)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "4950")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 246.0; 84 aligned letters; 44 identities; 40 mismatches; 68 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 246.0,
    aligned = 84:
        identities = 44,
        positives = 68,
        mismatches = 40.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 44)
            self.assertEqual(counts.mismatches, 40)
            self.assertEqual(counts.positives, 68)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|367014         0 TFNFMSRAN*VATMNASRTSDNLSFDRDGVDDNLCKHCIDIDVNLAFFEEQ 51
                  0 |||..|.|.|||.|.||..||......||..|..|.|||...|.|||...| 51
gi|296147         0 TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQ 51
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  51],
                              [  0,  51]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|367014048|ref|XM_003681476.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|367014048|ref|XM_003681476.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "367014048")
            self.assertEqual(alignment.target.annotations["gis"], "367014048")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003681476.1")
            self.assertEqual(alignment.target.annotations["length"], 4902)
            self.assertEqual(alignment.query.annotations["start"], 350)
            self.assertEqual(alignment.query.annotations["end"], 197)
            self.assertEqual(alignment.target.annotations["start"], 350)
            self.assertEqual(alignment.target.annotations["end"], 197)
            self.assertEqual(
                alignment.target.seq,
                "TFNFMSRAN*VATMNASRTSDNLSFDRDGVDDNLCKHCIDIDVNLAFFEEQ",
            )
            self.assertEqual(
                alignment.query.seq,
                "TFN*ISIAR*VASMKASKISDSRLRGIDGTVDSPCRHCIARVVILAFLDWQ",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 48.3)
            self.assertAlmostEqual(alignment.score, 99)
            self.assertEqual(alignment.shape, (2, 51))
            self.assertAlmostEqual(alignment.annotations["% identity"], 49.02)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 32)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.75)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "4950")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 44)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 99.0; 51 aligned letters; 25 identities; 26 mismatches; 32 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 99.0,
    aligned = 51:
        identities = 25,
        positives = 32,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 51)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 32)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|367014         0 TVLRISIDLSLACLMAELLFFASEDKSCNSEFNCL 35
                  0 |...||.|||||..|.|.|.|.||||..||...|| 35
gi|296147         0 TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL 35
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  35],
                              [  0,  35]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|367014048|ref|XM_003681476.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|367014048|ref|XM_003681476.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "367014048")
            self.assertEqual(alignment.target.annotations["gis"], "367014048")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003681476")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003681476.1")
            self.assertEqual(alignment.target.annotations["length"], 4902)
            self.assertEqual(alignment.query.annotations["start"], 140)
            self.assertEqual(alignment.query.annotations["end"], 35)
            self.assertEqual(alignment.target.annotations["start"], 140)
            self.assertEqual(alignment.target.annotations["end"], 35)
            self.assertEqual(
                alignment.target.seq, "TVLRISIDLSLACLMAELLFFASEDKSCNSEFNCL"
            )
            self.assertEqual(alignment.query.seq, "TLFNISMDLSLAWRMVEFLLFDSEDKERNSASSCL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 43.7)
            self.assertAlmostEqual(alignment.score, 89)
            self.assertEqual(alignment.shape, (2, 35))
            self.assertAlmostEqual(alignment.annotations["% identity"], 57.14)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.71)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "4950")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Torulaspora delbrueckii hypothetical protein (TDEL0E00700) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 90)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 30)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 89.0; 35 aligned letters; 20 identities; 15 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 89.0,
    aligned = 35:
        identities = 20,
        positives = 23,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 35)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|503027         0 IKQACEKSIEILQRSHSEEELVRHPDFVDPFITACLSGNAKLTSISMQSMQRISGIRCIC
                  0 |..|..||||||.|.||.|||.|||||..||..||.|.|||.|...||..|..|....|.
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|503027        60 TSKMESLLNALLKSTELAIDIQLK 84
                 60 .|.....|.|....|.||..|||| 84
gi|296147        60 RSRLSEILDAFIEATHLAMEIQLK 84
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  84],
                              [  0,  84]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50302786|ref|XM_451330.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50302786|ref|XM_451330.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50302786")
            self.assertEqual(alignment.target.annotations["gis"], "50302786")
            self.assertEqual(alignment.target.annotations["acc."], "XM_451330")
            self.assertEqual(alignment.target.annotations["accs."], "XM_451330")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_451330.1")
            self.assertEqual(alignment.target.annotations["length"], 4809)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 93)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "IKQACEKSIEILQRSHSEEELVRHPDFVDPFITACLSGNAKLTSISMQSMQRISGIRCICTSKMESLLNALLKSTELAIDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-20, places=20)
            self.assertAlmostEqual(alignment.annotations["bit score"], 103)
            self.assertAlmostEqual(alignment.score, 219)
            self.assertEqual(alignment.shape, (2, 84))
            self.assertAlmostEqual(alignment.annotations["% identity"], 51.19)
            self.assertEqual(alignment.annotations["identical"], 43)
            self.assertEqual(alignment.annotations["mismatches"], 41)
            self.assertEqual(alignment.annotations["positives"], 63)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 75.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284590")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Kluyveromyces lactis NRRL Y-1140 hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Kluyveromyces lactis NRRL Y-1140 hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 72)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 72)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 219.0; 84 aligned letters; 43 identities; 41 mismatches; 63 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 219.0,
    aligned = 84:
        identities = 43,
        positives = 63,
        mismatches = 41.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 84)
            self.assertEqual(counts.identities, 43)
            self.assertEqual(counts.mismatches, 41)
            self.assertEqual(counts.positives, 63)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|367029         0 KNLRASTEVQASEELAQRPNFVNPFIIACGTKNVKFTGIAIVCLQRLIVSRALPRARLSQ
                  0 |.......|...|||...|.|..||..||...|.|.|..|..|||.|......||.|||.
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|367029        60 VLEALQQATSAGLDVQLK 78
                 60 .|.|...||......||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|367029360|ref|XM_003663916.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|367029360|ref|XM_003663916.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "367029360")
            self.assertEqual(alignment.target.annotations["gis"], "367029360")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003663916")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003663916")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003663916.1")
            self.assertEqual(alignment.target.annotations["length"], 5145)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "KNLRASTEVQASEELAQRPNFVNPFIIACGTKNVKFTGIAIVCLQRLIVSRALPRARLSQVLEALQQATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-13, places=13)
            self.assertAlmostEqual(alignment.annotations["bit score"], 79.9)
            self.assertAlmostEqual(alignment.score, 168)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 39.74)
            self.assertEqual(alignment.annotations["identical"], 31)
            self.assertEqual(alignment.annotations["mismatches"], 47)
            self.assertEqual(alignment.annotations["positives"], 52)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "573729")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Myceliophthora thermophila ATCC 42464 hypothetical protein (MYCTH_2139484) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Myceliophthora thermophila ATCC 42464 hypothetical protein (MYCTH_2139484) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 168.0; 78 aligned letters; 31 identities; 47 mismatches; 52 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 168.0,
    aligned = 78:
        identities = 31,
        positives = 52,
        mismatches = 47.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 31)
            self.assertEqual(counts.mismatches, 47)
            self.assertEqual(counts.positives, 52)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|367039         0 KSLRASSEPQFADELAQRPNFVNPFIIACGTKNSKFTGIAIVCLQRLIIARAFPRSKLSQ
                  0 ||...........||...|.|..||..||...|.|.|..|..|||.|......|||.||.
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|367039        60 ILDALQQATSAGLDVQLK 78
                 60 ||||...||......||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|367039842|ref|XM_003650254.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|367039842|ref|XM_003650254.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "367039842")
            self.assertEqual(alignment.target.annotations["gis"], "367039842")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003650254")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003650254")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003650254.1")
            self.assertEqual(alignment.target.annotations["length"], 5163)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "KSLRASSEPQFADELAQRPNFVNPFIIACGTKNSKFTGIAIVCLQRLIIARAFPRSKLSQILDALQQATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-13, places=13)
            self.assertAlmostEqual(alignment.annotations["bit score"], 78.5)
            self.assertAlmostEqual(alignment.score, 165)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.03)
            self.assertEqual(alignment.annotations["identical"], 32)
            self.assertEqual(alignment.annotations["mismatches"], 46)
            self.assertEqual(alignment.annotations["positives"], 50)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.10)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "578455")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Thielavia terrestris NRRL 8126 hypothetical protein (THITE_2039383) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Thielavia terrestris NRRL 8126 hypothetical protein (THITE_2039383) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 165.0; 78 aligned letters; 32 identities; 46 mismatches; 50 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 165.0,
    aligned = 78:
        identities = 32,
        positives = 50,
        mismatches = 46.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 32)
            self.assertEqual(counts.mismatches, 46)
            self.assertEqual(counts.positives, 50)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302895         0 EELSQKVNFVNPFIIACGTKNAKFTAIAIVCLQRLIVAQALPRSKLNQVLEALMQATSAG
                  0 |||.....|..||..||...|||.|..|..|||.|......|||.|...|.|...||...
gi|296147         0 EELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLA

gi|302895        60 LDVQLK 66
                 60 ...||| 66
gi|296147        60 MEIQLK 66
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  66],
                              [  0,  66]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302895812|ref|XM_003046741.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302895812|ref|XM_003046741.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302895812")
            self.assertEqual(alignment.target.annotations["gis"], "302895812")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003046741")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003046741")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003046741.1")
            self.assertEqual(alignment.target.annotations["length"], 4878)
            self.assertEqual(alignment.query.annotations["start"], 150)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 141)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "EELSQKVNFVNPFIIACGTKNAKFTAIAIVCLQRLIVAQALPRSKLNQVLEALMQATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "EELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-12, places=12)
            self.assertAlmostEqual(alignment.annotations["bit score"], 77.1)
            self.assertAlmostEqual(alignment.score, 162)
            self.assertEqual(alignment.shape, (2, 66))
            self.assertAlmostEqual(alignment.annotations["% identity"], 42.42)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 48)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 72.73)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "660122")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nectria haematococca mpVI 77-13-4 hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nectria haematococca mpVI 77-13-4 hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 57)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 57)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 162.0; 66 aligned letters; 28 identities; 38 mismatches; 48 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 162.0,
    aligned = 66:
        identities = 28,
        positives = 48,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 66)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 48)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302403         0 ELTQRPNFVNPFVIACGTKNTKFTAIAIVCLQRLILVRALPRGKLSHVLEALREATSAGL
                  0 ||...|.|..|||.||...|.|.|..|..|||.|..|...||..||..|.|..|||....
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|302403        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302403860|ref|XM_002999723.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302403860|ref|XM_002999723.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302403860")
            self.assertEqual(alignment.target.annotations["gis"], "302403860")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002999723")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002999723")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002999723.1")
            self.assertEqual(alignment.target.annotations["length"], 5097)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 150)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "ELTQRPNFVNPFVIACGTKNTKFTAIAIVCLQRLILVRALPRGKLSHVLEALREATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-12, places=12)
            self.assertAlmostEqual(alignment.annotations["bit score"], 76.7)
            self.assertAlmostEqual(alignment.score, 161)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 46.15)
            self.assertEqual(alignment.annotations["identical"], 30)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 45)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 69.23)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "526221")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Verticillium albo-atrum VaMs.102 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Verticillium albo-atrum VaMs.102 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 161.0; 65 aligned letters; 30 identities; 35 mismatches; 45 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 161.0,
    aligned = 65:
        identities = 30,
        positives = 45,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 30)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 45)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|154323         0 DLTQRPNFVTPFLIACGTRNVKFTGIAVVCLQRLVVSRALPKSRLKEVLEALREATSAGL
                  0 .|...|.|..||..||..||.|.|..|..|||.|......|.|||.|.|.|..|||....
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|154323        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|154323271|ref|XM_001560900.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|154323271|ref|XM_001560900.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "154323271")
            self.assertEqual(alignment.target.annotations["gis"], "154323271")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001560900")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001560900")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001560900.1")
            self.assertEqual(alignment.target.annotations["length"], 3186)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 141)
            self.assertEqual(alignment.target.annotations["end"], 336)
            self.assertEqual(
                alignment.target.seq,
                "DLTQRPNFVTPFLIACGTRNVKFTGIAVVCLQRLVVSRALPKSRLKEVLEALREATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-12, places=12)
            self.assertAlmostEqual(alignment.annotations["bit score"], 75.3)
            self.assertAlmostEqual(alignment.score, 158)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.62)
            self.assertEqual(alignment.annotations["identical"], 29)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 45)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 69.23)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "332648")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Botryotinia fuckeliana B05.10 hypothetical protein (BC1G_00035) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Botryotinia fuckeliana B05.10 hypothetical protein (BC1G_00035) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 158.0; 65 aligned letters; 29 identities; 36 mismatches; 45 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 158.0,
    aligned = 65:
        identities = 29,
        positives = 45,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 29)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 45)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|389631         0 KSLNISSEAQLGPELTQKTNFANPFIIACGTKNAKFTGIAIVCLQRLIVSKALPRPRLNQ
                  0 ||..|........||.....||.||..||...|||.|..|..|||.|......||.||..
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|389631        60 VLEALQGATSAGLDVQLK 78
                 60 .|.|...||......||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|389631003|ref|XM_003713107.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|389631003|ref|XM_003713107.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "389631003")
            self.assertEqual(alignment.target.annotations["gis"], "389631003")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003713107")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003713107")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003713107.1")
            self.assertEqual(alignment.target.annotations["length"], 5566)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 293)
            self.assertEqual(alignment.target.annotations["end"], 527)
            self.assertEqual(
                alignment.target.seq,
                "KSLNISSEAQLGPELTQKTNFANPFIIACGTKNAKFTGIAIVCLQRLIVSKALPRPRLNQVLEALQGATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 73.5)
            self.assertAlmostEqual(alignment.score, 154)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 39.74)
            self.assertEqual(alignment.annotations["identical"], 31)
            self.assertEqual(alignment.annotations["mismatches"], 47)
            self.assertEqual(alignment.annotations["positives"], 49)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.82)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "242507")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Magnaporthe oryzae 70-15 hypothetical protein (MGG_07913) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Magnaporthe oryzae 70-15 hypothetical protein (MGG_07913) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 154.0; 78 aligned letters; 31 identities; 47 mismatches; 49 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 154.0,
    aligned = 78:
        identities = 31,
        positives = 49,
        mismatches = 47.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 31)
            self.assertEqual(counts.mismatches, 47)
            self.assertEqual(counts.positives, 49)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|336276         0 KSLKVTSEAQISAELSQRSNFVNPFIIACGTKNVKFTGIAIVCLQRLIASRALPRFKLSQ
                  0 ||...........||.....|..||..||...|.|.|..|..|||.|......||..||.
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|336276        60 VLEALQQATSAGLDVQLK 78
                 60 .|.|...||......||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|336276565|ref|XM_003352988.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|336276565|ref|XM_003352988.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "336276565")
            self.assertEqual(alignment.target.annotations["gis"], "336276565")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003352988")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003352988")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003352988.1")
            self.assertEqual(alignment.target.annotations["length"], 5166)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "KSLKVTSEAQISAELSQRSNFVNPFIIACGTKNVKFTGIAIVCLQRLIASRALPRFKLSQVLEALQQATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 72.5)
            self.assertAlmostEqual(alignment.score, 152)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.90)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 50)
            self.assertEqual(alignment.annotations["positives"], 49)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.82)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "771870")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Sordaria macrospora k-hell hypothetical protein (SMAC_03354), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Sordaria macrospora k-hell hypothetical protein (SMAC_03354), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 152.0; 78 aligned letters; 28 identities; 50 mismatches; 49 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 152.0,
    aligned = 78:
        identities = 28,
        positives = 49,
        mismatches = 50.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 50)
            self.assertEqual(counts.positives, 49)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|164425         0 KSLKVTSEAQISAELSQRSNFVNPFIIACGTKNVKFTGIAIVCLQRLIASRALPRFKLSQ
                  0 ||...........||.....|..||..||...|.|.|..|..|||.|......||..||.
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|164425        60 VLEALQQATSAGLDVQLK 78
                 60 .|.|...||......||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|164425502|ref|XM_955020.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|164425502|ref|XM_955020.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "164425502")
            self.assertEqual(alignment.target.annotations["gis"], "164425502")
            self.assertEqual(alignment.target.annotations["acc."], "XM_955020")
            self.assertEqual(alignment.target.annotations["accs."], "XM_955020")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_955020.2")
            self.assertEqual(alignment.target.annotations["length"], 5253)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "KSLKVTSEAQISAELSQRSNFVNPFIIACGTKNVKFTGIAIVCLQRLIASRALPRFKLSQVLEALQQATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 72.5)
            self.assertAlmostEqual(alignment.score, 152)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.90)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 50)
            self.assertEqual(alignment.annotations["positives"], 49)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.82)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "367110")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Neurospora crassa OR74A hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Neurospora crassa OR74A hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 152.0; 78 aligned letters; 28 identities; 50 mismatches; 49 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 152.0,
    aligned = 78:
        identities = 28,
        positives = 49,
        mismatches = 50.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 50)
            self.assertEqual(counts.positives, 49)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296807         0 DLARKPQFARPFVLACQTRHTRLAAIGVANLQRLVTIGALPQERLKDVLQGLHETANLSL
                  0 .|.|.|.||.|||||||.|...........||.|.|....|..||...|....|...|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|296807        60 EIQLK 65
                 60 ||||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296807956|ref|XM_002844271.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|296807956|ref|XM_002844271.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "296807956")
            self.assertEqual(alignment.target.annotations["gis"], "296807956")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002844271")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002844271")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002844271.1")
            self.assertEqual(alignment.target.annotations["length"], 5127)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLARKPQFARPFVLACQTRHTRLAAIGVANLQRLVTIGALPQERLKDVLQGLHETANLSLEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 71.6)
            self.assertAlmostEqual(alignment.score, 150)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 44)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "554155")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Arthroderma otae CBS 113480 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Arthroderma otae CBS 113480 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 150.0; 65 aligned letters; 28 identities; 37 mismatches; 44 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 150.0,
    aligned = 65:
        identities = 28,
        positives = 44,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 44)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|327295         0 DLARKPQFARPFVLACQTRHTRLAAIGVTNLQRLVTIGALPHERLKDVLQGLHETANLSL
                  0 .|.|.|.||.|||||||.|...........||.|.|....|..||...|....|...|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|327295        60 EIQLK 65
                 60 ||||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|327295565|ref|XM_003232430.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|327295565|ref|XM_003232430.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "327295565")
            self.assertEqual(alignment.target.annotations["gis"], "327295565")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003232430")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003232430")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003232430.1")
            self.assertEqual(alignment.target.annotations["length"], 5157)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLARKPQFARPFVLACQTRHTRLAAIGVTNLQRLVTIGALPHERLKDVLQGLHETANLSLEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 71.2)
            self.assertAlmostEqual(alignment.score, 149)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559305")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Trichophyton rubrum CBS 118892 hypothetical protein (TERG_07323) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Trichophyton rubrum CBS 118892 hypothetical protein (TERG_07323) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 149.0; 65 aligned letters; 28 identities; 37 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 149.0,
    aligned = 65:
        identities = 28,
        positives = 43,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|317026         0 DLVRKPKFANPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLAGLKETTNMSL
                  0 .|.|.|.||.||.|||.||.||.......|||.|....|.|..||...|....|.|....
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|317026        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|317026200|ref|XM_001389120.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|317026200|ref|XM_001389120.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "317026200")
            self.assertEqual(alignment.target.annotations["gis"], "317026200")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001389120")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001389120")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001389120.2")
            self.assertEqual(alignment.target.annotations["length"], 5229)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPKFANPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLAGLKETTNMSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 71.2)
            self.assertAlmostEqual(alignment.score, 149)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.62)
            self.assertEqual(alignment.annotations["identical"], 29)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "425011")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus niger CBS 513.88 endosomal peripheral membrane protein (Mon2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus niger CBS 513.88 endosomal peripheral membrane protein (Mon2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 149.0; 65 aligned letters; 29 identities; 36 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 149.0,
    aligned = 65:
        identities = 29,
        positives = 43,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 29)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156058         0 DLTQRANFVTPFLIACGTKNVKFTGIAVVCLQRLVVSRALPRSRLREVLEALREATSAGL
                  0 .|.....|..||..||...|.|.|..|..|||.|......|||||.|.|.|..|||....
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|156058        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156058004|ref|XM_001594876.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156058004|ref|XM_001594876.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156058004")
            self.assertEqual(alignment.target.annotations["gis"], "156058004")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001594876")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001594876")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001594876.1")
            self.assertEqual(alignment.target.annotations["length"], 4755)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLTQRANFVTPFLIACGTKNVKFTGIAVVCLQRLVVSRALPRSRLREVLEALREATSAGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8e-11, places=11)
            self.assertAlmostEqual(alignment.annotations["bit score"], 71.2)
            self.assertAlmostEqual(alignment.score, 149)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 44)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "665079")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Sclerotinia sclerotiorum 1980 hypothetical protein (SS1G_04734) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Sclerotinia sclerotiorum 1980 hypothetical protein (SS1G_04734) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 149.0; 65 aligned letters; 28 identities; 37 mismatches; 44 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 149.0,
    aligned = 65:
        identities = 28,
        positives = 44,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 44)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|315042         0 DLARKPQFSRPFVLACQTRHARLAAIGVANLQRLVTIGALPHERLKDVVQGLHETANLSL
                  0 .|.|.|.|..|||||||.|.|.........||.|.|....|..||........|...|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|315042        60 EIQLK 65
                 60 ||||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|315042717|ref|XM_003170687.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|315042717|ref|XM_003170687.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "315042717")
            self.assertEqual(alignment.target.annotations["gis"], "315042717")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003170687")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003170687")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003170687.1")
            self.assertEqual(alignment.target.annotations["length"], 5178)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLARKPQFSRPFVLACQTRHARLAAIGVANLQRLVTIGALPHERLKDVVQGLHETANLSLEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 70.3)
            self.assertAlmostEqual(alignment.score, 147)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.54)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 44)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "535722")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Arthroderma gypseum CBS 118893 hypothetical protein (MGYG_06723) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Arthroderma gypseum CBS 118893 hypothetical protein (MGYG_06723) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 147.0; 65 aligned letters; 27 identities; 38 mismatches; 44 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 147.0,
    aligned = 65:
        identities = 27,
        positives = 44,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 44)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|255947         0 DLVRKPNFVEPFIIACHTRHAKLAGIGVICLQRLIASRSLPSSRLKDVLGGLKETTSLSL
                  0 .|.|.|.|..||..||..|.||.......|||.|....|.|.|||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|255947        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|255947577|ref|XM_002564510.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|255947577|ref|XM_002564510.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "255947577")
            self.assertEqual(alignment.target.annotations["gis"], "255947577")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002564510")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002564510")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002564510.1")
            self.assertEqual(alignment.target.annotations["length"], 5004)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPNFVEPFIIACHTRHAKLAGIGVICLQRLIASRSLPSSRLKDVLGGLKETTSLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 69.8)
            self.assertAlmostEqual(alignment.score, 146)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "500485")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Penicillium chrysogenum Wisconsin 54-1255 hypothetical protein (Pc22g05210) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Penicillium chrysogenum Wisconsin 54-1255 hypothetical protein (Pc22g05210) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 146.0; 65 aligned letters; 28 identities; 37 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 146.0,
    aligned = 65:
        identities = 28,
        positives = 43,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|121708         0 DLVRKPKFVDPFILACHSRHAKLSGIGVVCLQRLVASRSLPSSRLKDVLGGLRETTSLNL
                  0 .|.|.|.|..||.|||.||.||.......|||.|....|.|.|||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|121708        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|121708212|ref|XM_001272061.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|121708212|ref|XM_001272061.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "121708212")
            self.assertEqual(alignment.target.annotations["gis"], "121708212")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001272061")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001272061")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001272061.1")
            self.assertEqual(alignment.target.annotations["length"], 5226)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 150)
            self.assertEqual(alignment.target.annotations["end"], 345)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPKFVDPFILACHSRHAKLSGIGVVCLQRLVASRSLPSSRLKDVLGGLRETTSLNLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 69.8)
            self.assertAlmostEqual(alignment.score, 146)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.62)
            self.assertEqual(alignment.annotations["identical"], 29)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.62)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "344612")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus clavatus NRRL 1 conserved hypothetical protein (ACLA_051080), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus clavatus NRRL 1 conserved hypothetical protein (ACLA_051080), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 146.0; 65 aligned letters; 29 identities; 36 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 146.0,
    aligned = 65:
        identities = 29,
        positives = 42,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 29)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|303311         0 KAVPSTSEVQLAADLVRRPQFANPFILACHTRHAKLAAVGVGCIHRLVASGALPSEQLKD
                  0 |.......|.....|.|.|.||.||.|||..|.||.......|...|......|...|..
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|303311        60 VVDGLHETTNLSLDVQLK 78
                 60 ..|...|.|.|....||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|303311206|ref|XM_003065569.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|303311206|ref|XM_003065569.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "303311206")
            self.assertEqual(alignment.target.annotations["gis"], "303311206")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003065569")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003065569")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003065569.1")
            self.assertEqual(alignment.target.annotations["length"], 5588)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 289)
            self.assertEqual(alignment.target.annotations["end"], 523)
            self.assertEqual(
                alignment.target.seq,
                "KAVPSTSEVQLAADLVRRPQFANPFILACHTRHAKLAAVGVGCIHRLVASGALPSEQLKDVVDGLHETTNLSLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 69.3)
            self.assertAlmostEqual(alignment.score, 145)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.33)
            self.assertEqual(alignment.annotations["identical"], 26)
            self.assertEqual(alignment.annotations["mismatches"], 52)
            self.assertEqual(alignment.annotations["positives"], 47)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.26)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "222929")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Coccidioides posadasii C735 delta SOWgp HEAT repeat containing protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Coccidioides posadasii C735 delta SOWgp HEAT repeat containing protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 145.0; 78 aligned letters; 26 identities; 52 mismatches; 47 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 145.0,
    aligned = 78:
        identities = 26,
        positives = 47,
        mismatches = 52.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 26)
            self.assertEqual(counts.mismatches, 52)
            self.assertEqual(counts.positives, 47)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|709935         0 DLVRKPKFVDPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLGGLKETTSLSL
                  0 .|.|.|.|..||.|||.||.||.......|||.|....|.|..||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|709935        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|70993553|ref|XM_746531.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|70993553|ref|XM_746531.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "70993553")
            self.assertEqual(alignment.target.annotations["gis"], "70993553")
            self.assertEqual(alignment.target.annotations["acc."], "XM_746531")
            self.assertEqual(alignment.target.annotations["accs."], "XM_746531")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_746531.1")
            self.assertEqual(alignment.target.annotations["length"], 5067)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 45)
            self.assertEqual(alignment.target.annotations["end"], 240)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPKFVDPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLGGLKETTSLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 69.3)
            self.assertAlmostEqual(alignment.score, 145)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.62)
            self.assertEqual(alignment.annotations["identical"], 29)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.08)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "330879")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus fumigatus Af293 endosomal peripheral membrane protein (Mon2) (AFUA_4G12070), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus fumigatus Af293 endosomal peripheral membrane protein (Mon2) (AFUA_4G12070), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 145.0; 65 aligned letters; 29 identities; 36 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 145.0,
    aligned = 65:
        identities = 29,
        positives = 41,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 29)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|212542         0 DLIRRPHFVTPFILACQTRQSKLASIGVVCLQRLATSHAISPSRLNDTLSALGDITGLSQ
                  0 .|.|.|.|..||.||||.|..|.......|||.|.|...|..|||...|.|....|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|212542        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|212542406|ref|XM_002151322.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|212542406|ref|XM_002151322.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "212542406")
            self.assertEqual(alignment.target.annotations["gis"], "212542406")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002151322")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002151322")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002151322.1")
            self.assertEqual(alignment.target.annotations["length"], 5214)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLIRRPHFVTPFILACQTRQSKLASIGVVCLQRLATSHAISPSRLNDTLSALGDITGLSQDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 68.9)
            self.assertAlmostEqual(alignment.score, 144)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 44)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "441960")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Penicillium marneffei ATCC 18224 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Penicillium marneffei ATCC 18224 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 144.0; 65 aligned letters; 28 identities; 37 mismatches; 44 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 144.0,
    aligned = 65:
        identities = 28,
        positives = 44,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 44)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|119500         0 DLVRKPRFVDPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLGGLKETTSLSL
                  0 .|.|.|.|..||.|||.||.||.......|||.|....|.|..||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|119500        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|119500139|ref|XM_001266826.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|119500139|ref|XM_001266826.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "119500139")
            self.assertEqual(alignment.target.annotations["gis"], "119500139")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001266826")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001266826")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001266826.1")
            self.assertEqual(alignment.target.annotations["length"], 4884)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 45)
            self.assertEqual(alignment.target.annotations["end"], 240)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPRFVDPFILACHSRHAKLAGIGVVCLQRLVASRSLPSERLKDVLGGLKETTSLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 68.9)
            self.assertAlmostEqual(alignment.score, 144)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.62)
            self.assertEqual(alignment.annotations["identical"], 29)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.08)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "331117")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Neosartorya fischeri NRRL 181 conserved hypothetical protein (NFIA_104180) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Neosartorya fischeri NRRL 181 conserved hypothetical protein (NFIA_104180) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 144.0; 65 aligned letters; 29 identities; 36 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 144.0,
    aligned = 65:
        identities = 29,
        positives = 41,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 29)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|119194         0 KALPSTSEVQLAADLVRRPQFANPFILACHTRHAKLAAVGVGCIHRLVASGALPSEQLKD
                  0 |.......|.....|.|.|.||.||.|||..|.||.......|...|......|...|..
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|119194        60 VVDGLHETTNLSLDVQLK 78
                 60 ..|...|.|.|....||| 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|119194522|ref|XM_001247864.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|119194522|ref|XM_001247864.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "119194522")
            self.assertEqual(alignment.target.annotations["gis"], "119194522")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001247864")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001247864")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001247864.1")
            self.assertEqual(alignment.target.annotations["length"], 5163)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "KALPSTSEVQLAADLVRRPQFANPFILACHTRHAKLAAVGVGCIHRLVASGALPSEQLKDVVDGLHETTNLSLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 4e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 68.9)
            self.assertAlmostEqual(alignment.score, 144)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 33.33)
            self.assertEqual(alignment.annotations["identical"], 26)
            self.assertEqual(alignment.annotations["mismatches"], 52)
            self.assertEqual(alignment.annotations["positives"], 47)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.26)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "246410")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Coccidioides immitis RS hypothetical protein (CIMG_01636) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Coccidioides immitis RS hypothetical protein (CIMG_01636) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 144.0; 78 aligned letters; 26 identities; 52 mismatches; 47 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 144.0,
    aligned = 78:
        identities = 26,
        positives = 47,
        mismatches = 52.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 26)
            self.assertEqual(counts.mismatches, 52)
            self.assertEqual(counts.positives, 47)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|238486         0 DLVRKPKFVDPFILACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLSGLKETTNLSL
                  0 .|.|.|.|..||.|||..|.||.......|||.|......|..||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|238486        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|238486173|ref|XM_002374284.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|238486173|ref|XM_002374284.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "238486173")
            self.assertEqual(alignment.target.annotations["gis"], "238486173")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002374284")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002374284")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002374284.1")
            self.assertEqual(alignment.target.annotations["length"], 5160)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLVRKPKFVDPFILACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLSGLKETTNLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-10, places=10)
            self.assertAlmostEqual(alignment.annotations["bit score"], 68.0)
            self.assertAlmostEqual(alignment.score, 142)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.54)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.62)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "332952")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus flavus NRRL3357 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus flavus NRRL3357 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 142.0; 65 aligned letters; 27 identities; 38 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 142.0,
    aligned = 65:
        identities = 27,
        positives = 42,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|505475         0 QDLKKDEKIAQPLVLACSSRNAKLTAIAVPLIQRLLAISALSDKSIPSVLGALEEATHLG
                  0 ..|......|.|.||||.|||||.|..|....|.|..............|.|..|||||.
gi|296147         0 EELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLA

gi|505475        60 VEIQLK 66
                 60 .||||| 66
gi|296147        60 MEIQLK 66
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  66],
                              [  0,  66]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50547540|ref|XM_501240.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50547540|ref|XM_501240.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50547540")
            self.assertEqual(alignment.target.annotations["gis"], "50547540")
            self.assertEqual(alignment.target.annotations["acc."], "XM_501240")
            self.assertEqual(alignment.target.annotations["accs."], "XM_501240")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_501240.1")
            self.assertEqual(alignment.target.annotations["length"], 3855)
            self.assertEqual(alignment.query.annotations["start"], 150)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 117)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(
                alignment.target.seq,
                "QDLKKDEKIAQPLVLACSSRNAKLTAIAVPLIQRLLAISALSDKSIPSVLGALEEATHLGVEIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "EELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 67.0)
            self.assertAlmostEqual(alignment.score, 140)
            self.assertEqual(alignment.shape, (2, 66))
            self.assertAlmostEqual(alignment.annotations["% identity"], 42.42)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.64)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284591")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Yarrowia lipolytica YALI0B22858p (YALI0B22858g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Yarrowia lipolytica YALI0B22858p (YALI0B22858g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 57)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 57)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 140.0; 66 aligned letters; 28 identities; 38 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 140.0,
    aligned = 66:
        identities = 28,
        positives = 42,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 66)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|242768         0 DLIRRPHFVTPFILACQTRQSKLASIGVVCLQRLATSHAISPHRLNDTLSALRDITGLGQ
                  0 .|.|.|.|..||.||||.|..|.......|||.|.|...|...||...|.|....|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|242768        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|242768840|ref|XM_002341608.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|242768840|ref|XM_002341608.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "242768840")
            self.assertEqual(alignment.target.annotations["gis"], "242768840")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002341608")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002341608")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002341608.1")
            self.assertEqual(alignment.target.annotations["length"], 5181)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLIRRPHFVTPFILACQTRQSKLASIGVVCLQRLATSHAISPHRLNDTLSALRDITGLGQDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 66.6)
            self.assertAlmostEqual(alignment.score, 139)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.54)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.62)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "441959")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Talaromyces stipitatus ATCC 10500 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Talaromyces stipitatus ATCC 10500 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 139.0; 65 aligned letters; 27 identities; 38 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 139.0,
    aligned = 65:
        identities = 27,
        positives = 42,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|115391         0 DLARKPKFVDPFILACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLAGLKETTSLSL
                  0 .|.|.|.|..||.|||..|.||.......|||.|......|..||...|....|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|115391        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|115391062|ref|XM_001213036.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|115391062|ref|XM_001213036.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "115391062")
            self.assertEqual(alignment.target.annotations["gis"], "115391062")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001213036")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001213036")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001213036.1")
            self.assertEqual(alignment.target.annotations["length"], 4971)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLARKPKFVDPFILACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLAGLKETTSLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 66.6)
            self.assertAlmostEqual(alignment.score, 139)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.54)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 38)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.08)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "341663")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus terreus NIH2624 conserved hypothetical protein (ATEG_03858) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus terreus NIH2624 conserved hypothetical protein (ATEG_03858) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 139.0; 65 aligned letters; 27 identities; 38 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 139.0,
    aligned = 65:
        identities = 27,
        positives = 41,
        mismatches = 38.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 38)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|261194         0 DLIRKPQFVKPFVIACQTRHGRLAAIGVVCIQRLVASRALPPELLRDVLDGLHETTNLGL
                  0 .|.|.|.|..|||.|||.|..........|.|.|......|...|...||...|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|261194        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|261194600|ref|XM_002623659.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|261194600|ref|XM_002623659.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "261194600")
            self.assertEqual(alignment.target.annotations["gis"], "261194600")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002623659")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002623659")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002623659.1")
            self.assertEqual(alignment.target.annotations["length"], 5331)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 246)
            self.assertEqual(alignment.target.annotations["end"], 441)
            self.assertEqual(
                alignment.target.seq,
                "DLIRKPQFVKPFVIACQTRHGRLAAIGVVCIQRLVASRALPPELLRDVLDGLHETTNLGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 65.2)
            self.assertAlmostEqual(alignment.score, 136)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.92)
            self.assertEqual(alignment.annotations["identical"], 24)
            self.assertEqual(alignment.annotations["mismatches"], 41)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.08)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559298")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ajellomyces dermatitidis SLH14081 endosomal peripheral membrane protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ajellomyces dermatitidis SLH14081 endosomal peripheral membrane protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 136.0; 65 aligned letters; 24 identities; 41 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 136.0,
    aligned = 65:
        identities = 24,
        positives = 41,
        mismatches = 41.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 24)
            self.assertEqual(counts.mismatches, 41)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|398410         0 DLSRRPAFIEPFLVACGTRNPKFAGPGIICLQKLVIVRGLPKARLQDALEAFNACTDLGQ
                  0 .|.|.|.|..||..||..||.|.......|||.|..|...|..||...|.||...|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|398410        60 DIQLK 65
                 60 .|||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|398410919|ref|XM_003856759.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|398410919|ref|XM_003856759.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "398410919")
            self.assertEqual(alignment.target.annotations["gis"], "398410919")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003856759")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003856759")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003856759.1")
            self.assertEqual(alignment.target.annotations["length"], 5061)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "DLSRRPAFIEPFLVACGTRNPKFAGPGIICLQKLVIVRGLPKARLQDALEAFNACTDLGQDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 9e-09, places=9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 64.3)
            self.assertAlmostEqual(alignment.score, 134)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 43.08)
            self.assertEqual(alignment.annotations["identical"], 28)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 39)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "336722")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Mycosphaerella graminicola IPO323 hypothetical protein (MYCGRDRAFT_67581) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Mycosphaerella graminicola IPO323 hypothetical protein (MYCGRDRAFT_67581) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 134.0; 65 aligned letters; 28 identities; 37 mismatches; 39 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 134.0,
    aligned = 65:
        identities = 28,
        positives = 39,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 28)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 39)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|295669         0 DLLRKPHFVKPFVIACQTRHARLAAIGVVGVQRLVASRALPPERLRDVLNALQETTNLGL
                  0 .|.|.|.|..|||.|||.|.|..........|.|......|..||...|.|..|.|.|..
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAM

gi|295669        60 DVQLK 65
                 60 ..||| 65
gi|296147        60 EIQLK 65
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  65],
                              [  0,  65]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|295669495|ref|XM_002795250.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|295669495|ref|XM_002795250.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "295669495")
            self.assertEqual(alignment.target.annotations["gis"], "295669495")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002795250")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002795250")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002795250.1")
            self.assertEqual(alignment.target.annotations["length"], 5465)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 344)
            self.assertEqual(alignment.target.annotations["end"], 539)
            self.assertEqual(
                alignment.target.seq,
                "DLLRKPHFVKPFVIACQTRHARLAAIGVVGVQRLVASRALPPERLRDVLNALQETTNLGLDVQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-08, places=8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 63.4)
            self.assertAlmostEqual(alignment.score, 132)
            self.assertEqual(alignment.shape, (2, 65))
            self.assertAlmostEqual(alignment.annotations["% identity"], 38.46)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 40)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.15)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "502779")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Paracoccidioides brasiliensis Pb01 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Paracoccidioides brasiliensis Pb01 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 56)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 56)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 132.0; 65 aligned letters; 25 identities; 40 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 132.0,
    aligned = 65:
        identities = 25,
        positives = 43,
        mismatches = 40.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 65)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 40)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|504227         0 KSYQPQEKIHDISQNEIKMDILKPFLISCNTGNAKFATISIPIIHKLIIGEIIPVECLNE
                  0 ||.......|.....|...|...||...|...|||..|........|.....||...|.|
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|504227        60 LLDSLKEATNLATDIQLR 78
                 60 .||...|||.||..|||. 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|50422728|ref|XM_459941.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|50422728|ref|XM_459941.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "50422728")
            self.assertEqual(alignment.target.annotations["gis"], "50422728")
            self.assertEqual(alignment.target.annotations["acc."], "XM_459941")
            self.assertEqual(alignment.target.annotations["accs."], "XM_459941")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_459941.1")
            self.assertEqual(alignment.target.annotations["length"], 4800)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 108)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "KSYQPQEKIHDISQNEIKMDILKPFLISCNTGNAKFATISIPIIHKLIIGEIIPVECLNELLDSLKEATNLATDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 60.6)
            self.assertAlmostEqual(alignment.score, 126)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.62)
            self.assertEqual(alignment.annotations["identical"], 27)
            self.assertEqual(alignment.annotations["mismatches"], 51)
            self.assertEqual(alignment.annotations["positives"], 46)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.97)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "284592")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Debaryomyces hansenii CBS767 DEHA2E14608p (DEHA2E14608g) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Debaryomyces hansenii CBS767 DEHA2E14608p (DEHA2E14608g) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 126.0; 78 aligned letters; 27 identities; 51 mismatches; 46 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 126.0,
    aligned = 78:
        identities = 27,
        positives = 46,
        mismatches = 51.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 27)
            self.assertEqual(counts.mismatches, 51)
            self.assertEqual(counts.positives, 46)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|126258         0 KSIHDITNEQHRQHIIAPFVASCRTGNAKIATIAIPTIHKLIMAGVVPLGSLGSLVDSLM
                  0 |..|.............|||..|...|||..|.|......|......|...|....|...
gi|296147         0 KRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI

gi|126258        60 EASHLAVDIQLR 72
                 60 ||.|||..|||. 72
gi|296147        60 EATHLAMEIQLK 72
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  72],
                              [  0,  72]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|126258058|ref|XM_001387099.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|126258058|ref|XM_001387099.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "126258058")
            self.assertEqual(alignment.target.annotations["gis"], "126258058")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001387099")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001387099")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001387099.1")
            self.assertEqual(alignment.target.annotations["length"], 4755)
            self.assertEqual(alignment.query.annotations["start"], 132)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 126)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "KSIHDITNEQHRQHIIAPFVASCRTGNAKIATIAIPTIHKLIMAGVVPLGSLGSLVDSLMEASHLAVDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "KRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 59.7)
            self.assertAlmostEqual(alignment.score, 124)
            self.assertEqual(alignment.shape, (2, 72))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.94)
            self.assertEqual(alignment.annotations["identical"], 23)
            self.assertEqual(alignment.annotations["mismatches"], 49)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 56.94)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "322104")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Scheffersomyces stipitis CBS 6054 chromosome 1",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Scheffersomyces stipitis CBS 6054 chromosome 1",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 62)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 62)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 124.0; 72 aligned letters; 23 identities; 49 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 124.0,
    aligned = 72:
        identities = 23,
        positives = 41,
        mismatches = 49.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 72)
            self.assertEqual(counts.identities, 23)
            self.assertEqual(counts.mismatches, 49)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302663         0 DLARKPQFARPFVLACQTRQTRLAAIGVTNLQRLVTIGALPHERLKDVLQGLHETANLS
                  0 .|.|.|.||.|||||||.|...........||.|.|....|..||...|....|...|.
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLA

gi|302663        59
                 59
gi|296147        59
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  59],
                              [  0,  59]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302663055|ref|XM_003023130.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302663055|ref|XM_003023130.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302663055")
            self.assertEqual(alignment.target.annotations["gis"], "302663055")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003023130")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003023130")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003023130.1")
            self.assertEqual(alignment.target.annotations["length"], 5163)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 330)
            self.assertEqual(alignment.target.annotations["start"], 108)
            self.assertEqual(alignment.target.annotations["end"], 285)
            self.assertEqual(
                alignment.target.seq,
                "DLARKPQFARPFVLACQTRQTRLAAIGVTNLQRLVTIGALPHERLKDVLQGLHETANLS",
            )
            self.assertEqual(
                alignment.query.seq,
                "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-07)
            self.assertAlmostEqual(alignment.annotations["bit score"], 59.3)
            self.assertAlmostEqual(alignment.score, 123)
            self.assertEqual(alignment.shape, (2, 59))
            self.assertAlmostEqual(alignment.annotations["% identity"], 38.98)
            self.assertEqual(alignment.annotations["identical"], 23)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 36)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 61.02)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "663202")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Trichophyton verrucosum HKI 0517 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Trichophyton verrucosum HKI 0517 endosomal peripheral membrane protein (Mon2), putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 51)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 51)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 123.0; 59 aligned letters; 23 identities; 36 mismatches; 36 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 123.0,
    aligned = 59:
        identities = 23,
        positives = 36,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 59)
            self.assertEqual(counts.identities, 23)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 36)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|255728         0 PFILACKSGNIKLTNTATPVIYKLILAHAIPEENIPELLQALLEASNLAIDIQLR 55
                  0 ||.|||.|.|.|.|..|......|.....||.....|.|.|..||..||..|||. 55
gi|296147         0 PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|255728730|ref|XM_002549245.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|255728730|ref|XM_002549245.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "255728730")
            self.assertEqual(alignment.target.annotations["gis"], "255728730")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002549245")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002549245")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002549245.1")
            self.assertEqual(alignment.target.annotations["length"], 4671)
            self.assertEqual(alignment.query.annotations["start"], 183)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 177)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "PFILACKSGNIKLTNTATPVIYKLILAHAIPEENIPELLQALLEASNLAIDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-06)
            self.assertAlmostEqual(alignment.annotations["bit score"], 57.0)
            self.assertAlmostEqual(alignment.score, 118)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.82)
            self.assertEqual(alignment.annotations["identical"], 23)
            self.assertEqual(alignment.annotations["mismatches"], 32)
            self.assertEqual(alignment.annotations["positives"], 36)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.45)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "294747")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida tropicalis MYA-3404 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida tropicalis MYA-3404 conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 118.0; 55 aligned letters; 23 identities; 32 mismatches; 36 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 118.0,
    aligned = 55:
        identities = 23,
        positives = 36,
        mismatches = 32.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 23)
            self.assertEqual(counts.mismatches, 32)
            self.assertEqual(counts.positives, 36)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|171682         0 RQTYTIPELTQRPNFVNPFIIACGTKNVKFTGIAI 35
                  0 .......||...|.|..||..||...|.|.|..|. 35
gi|296147         0 KRVHSFEELERHPDFALPFVLACQSRNAKMTTLAM 35
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  35],
                              [  0,  35]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|171682617|ref|XM_001906217.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|171682617|ref|XM_001906217.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "171682617")
            self.assertEqual(alignment.target.annotations["gis"], "171682617")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001906217")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001906217")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001906217.1")
            self.assertEqual(alignment.target.annotations["length"], 4959)
            self.assertEqual(alignment.query.annotations["start"], 132)
            self.assertEqual(alignment.query.annotations["end"], 237)
            self.assertEqual(alignment.target.annotations["start"], 10)
            self.assertEqual(alignment.target.annotations["end"], 115)
            self.assertEqual(
                alignment.target.seq, "RQTYTIPELTQRPNFVNPFIIACGTKNVKFTGIAI"
            )
            self.assertEqual(alignment.query.seq, "KRVHSFEELERHPDFALPFVLACQSRNAKMTTLAM")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-06)
            self.assertAlmostEqual(alignment.annotations["bit score"], 38.6)
            self.assertAlmostEqual(alignment.score, 78)
            self.assertEqual(alignment.shape, (2, 35))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.29)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 23)
            self.assertEqual(alignment.annotations["positives"], 24)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 68.57)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "515849")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Podospora anserina S mat+ hypothetical protein (PODANSg3280) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Podospora anserina S mat+ hypothetical protein (PODANSg3280) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 52)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 30)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 78.0; 35 aligned letters; 12 identities; 23 mismatches; 24 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 78.0,
    aligned = 35:
        identities = 12,
        positives = 24,
        mismatches = 23.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 35)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 23)
            self.assertEqual(counts.positives, 24)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|171682         0 LPRSRLSQVLEALQQATSAGLDVQLK 26
                  0 .||||||..|.|...||......||| 26
gi|296147         0 IPRSRLSEILDAFIEATHLAMEIQLK 26
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  26],
                              [  0,  26]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|171682617|ref|XM_001906217.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|171682617|ref|XM_001906217.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "171682617")
            self.assertEqual(alignment.target.annotations["gis"], "171682617")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001906217")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001906217")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001906217.1")
            self.assertEqual(alignment.target.annotations["length"], 4959)
            self.assertEqual(alignment.query.annotations["start"], 270)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 117)
            self.assertEqual(alignment.target.annotations["end"], 195)
            self.assertEqual(alignment.target.seq, "LPRSRLSQVLEALQQATSAGLDVQLK")
            self.assertEqual(alignment.query.seq, "IPRSRLSEILDAFIEATHLAMEIQLK")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-06)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.3)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 26))
            self.assertAlmostEqual(alignment.annotations["% identity"], 50.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 21)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 80.77)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "515849")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Podospora anserina S mat+ hypothetical protein (PODANSg3280) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Podospora anserina S mat+ hypothetical protein (PODANSg3280) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 52)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 22)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 73.0; 26 aligned letters; 13 identities; 13 mismatches; 21 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 73.0,
    aligned = 26:
        identities = 13,
        positives = 21,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 26)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 21)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|460402         0 VKDAAEHAILKLRSLSSPSEIAHNEDILNIFLMACEVRNVKMSVIGLSCLQKLISHDVVA
                  0 ...|....|..|....|..|.....|....|..||..||.||......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|460402        60 TSALKEILDTLKDHGEMADE 80
                 60 .|.|.||||........|.| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|460402609|ref|XM_004246756.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|460402609|ref|XM_004246756.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "460402609")
            self.assertEqual(alignment.target.annotations["gis"], "460402609")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004246756")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004246756")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004246756.1")
            self.assertEqual(alignment.target.annotations["length"], 5431)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 402)
            self.assertEqual(alignment.target.annotations["end"], 642)
            self.assertEqual(
                alignment.target.seq,
                "VKDAAEHAILKLRSLSSPSEIAHNEDILNIFLMACEVRNVKMSVIGLSCLQKLISHDVVATSALKEILDTLKDHGEMADE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 53.3)
            self.assertAlmostEqual(alignment.score, 110)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.25)
            self.assertEqual(alignment.annotations["identical"], 25)
            self.assertEqual(alignment.annotations["mismatches"], 55)
            self.assertEqual(alignment.annotations["positives"], 44)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "4081")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Solanum lycopersicum protein MON2 homolog (LOC101244609), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Solanum lycopersicum protein MON2 homolog (LOC101244609), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 110.0; 80 aligned letters; 25 identities; 55 mismatches; 44 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 110.0,
    aligned = 80:
        identities = 25,
        positives = 44,
        mismatches = 55.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 25)
            self.assertEqual(counts.mismatches, 55)
            self.assertEqual(counts.positives, 44)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|684672         0 KSYSLVVPIQEINKEDHKEEILKPFILSCKSGNIKLTNISIPVIHKLILAHLIPELDITQ
                  0 ||.....................||.|.|.|.|.|.|.........|.....||......
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|684672        60 VLLCLLEASNLAVDIQLR 78
                 60 .|....||..||..|||. 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|68467204|ref|XM_717171.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|68467204|ref|XM_717171.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "68467204")
            self.assertEqual(alignment.target.annotations["gis"], "68467204")
            self.assertEqual(alignment.target.annotations["acc."], "XM_717171")
            self.assertEqual(alignment.target.annotations["accs."], "XM_717171")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_717171.1")
            self.assertEqual(alignment.target.annotations["length"], 4905)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 108)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "KSYSLVVPIQEINKEDHKEEILKPFILSCKSGNIKLTNISIPVIHKLILAHLIPELDITQVLLCLLEASNLAVDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 53.3)
            self.assertAlmostEqual(alignment.score, 110)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 26.92)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 57)
            self.assertEqual(alignment.annotations["positives"], 45)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "237561")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida albicans SC5314 hypothetical protein (CaO19_12405) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida albicans SC5314 hypothetical protein (CaO19_12405) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 110.0; 78 aligned letters; 21 identities; 57 mismatches; 45 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 110.0,
    aligned = 78:
        identities = 21,
        positives = 45,
        mismatches = 57.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 57)
            self.assertEqual(counts.positives, 45)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|684674         0 KSYSLVVPIQEINKEDHKEEILKPFILSCKSGNIKLTNISIPVIHKLILAHLIPELDITQ
                  0 ||.....................||.|.|.|.|.|.|.........|.....||......
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|684674        60 VLLCLLEASNLAVDIQLR 78
                 60 .|....||..||..|||. 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|68467433|ref|XM_717057.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|68467433|ref|XM_717057.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "68467433")
            self.assertEqual(alignment.target.annotations["gis"], "68467433")
            self.assertEqual(alignment.target.annotations["acc."], "XM_717057")
            self.assertEqual(alignment.target.annotations["accs."], "XM_717057")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_717057.1")
            self.assertEqual(alignment.target.annotations["length"], 4905)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 108)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "KSYSLVVPIQEINKEDHKEEILKPFILSCKSGNIKLTNISIPVIHKLILAHLIPELDITQVLLCLLEASNLAVDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 53.3)
            self.assertAlmostEqual(alignment.score, 110)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 26.92)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 57)
            self.assertEqual(alignment.annotations["positives"], 45)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.69)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "237561")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida albicans SC5314 hypothetical protein (MON2) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida albicans SC5314 hypothetical protein (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 110.0; 78 aligned letters; 21 identities; 57 mismatches; 45 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 110.0,
    aligned = 78:
        identities = 21,
        positives = 45,
        mismatches = 57.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 57)
            self.assertEqual(counts.positives, 45)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|317144         0 ACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLSGLKETTNLSLDIQLK 51
                  0 ||..|.||.......|||.|......|..||...|....|.|.|...|||| 51
gi|296147         0 ACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 51
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  51],
                              [  0,  51]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|317144425|ref|XM_001820059.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|317144425|ref|XM_001820059.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "317144425")
            self.assertEqual(alignment.target.annotations["gis"], "317144425")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001820059")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001820059")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001820059.2")
            self.assertEqual(alignment.target.annotations["length"], 5076)
            self.assertEqual(alignment.query.annotations["start"], 195)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 144)
            self.assertEqual(alignment.target.annotations["end"], 297)
            self.assertEqual(
                alignment.target.seq,
                "ACHTRHAKLAGIGVVCLQRLVASRALPSERLKDVLSGLKETTNLSLDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "ACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 51.5)
            self.assertAlmostEqual(alignment.score, 106)
            self.assertEqual(alignment.shape, (2, 51))
            self.assertAlmostEqual(alignment.annotations["% identity"], 39.22)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 31)
            self.assertEqual(alignment.annotations["positives"], 33)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.71)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "510516")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aspergillus oryzae RIB40 endosomal peripheral membrane protein (Mon2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aspergillus oryzae RIB40 endosomal peripheral membrane protein (Mon2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 44)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 44)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 106.0; 51 aligned letters; 20 identities; 31 mismatches; 33 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 106.0,
    aligned = 51:
        identities = 20,
        positives = 33,
        mismatches = 31.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 51)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 31)
            self.assertEqual(counts.positives, 33)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|241950         0 KSYSSVVPIQEINKENHREEVLKPFILSCKSGNIKLTNISIPVIYKLILAHLIPELDISQ
                  0 ||.....................||.|.|.|.|.|.|.........|.....||....|.
gi|296147         0 KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE

gi|241950        60 VLLCLLEASNLAVDIQLR 78
                 60 .|....||..||..|||. 78
gi|296147        60 ILDAFIEATHLAMEIQLK 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|241950270|ref|XM_002417813.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|241950270|ref|XM_002417813.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "241950270")
            self.assertEqual(alignment.target.annotations["gis"], "241950270")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002417813")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002417813")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002417813.1")
            self.assertEqual(alignment.target.annotations["length"], 4944)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 108)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "KSYSSVVPIQEINKENHREEVLKPFILSCKSGNIKLTNISIPVIYKLILAHLIPELDISQVLLCLLEASNLAVDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "KSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 7e-05)
            self.assertAlmostEqual(alignment.annotations["bit score"], 51.5)
            self.assertAlmostEqual(alignment.score, 106)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 28.21)
            self.assertEqual(alignment.annotations["identical"], 22)
            self.assertEqual(alignment.annotations["mismatches"], 56)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.13)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "573826")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Candida dubliniensis CD36 SEC7-family member, endocytosis and vacuole integrity protein, putative (CD36_12180) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Candida dubliniensis CD36 SEC7-family member, endocytosis and vacuole integrity protein, putative (CD36_12180) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 106.0; 78 aligned letters; 22 identities; 56 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 106.0,
    aligned = 78:
        identities = 22,
        positives = 43,
        mismatches = 56.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 22)
            self.assertEqual(counts.mismatches, 56)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|448082         0 PFILSSHNWNAKTATISIPIIHKLIISNAVSREDLEQLLHALKEASNLALDIQLR 55
                  0 ||.|.....|||..|........|.......|..|...|.|..||..||..|||. 55
gi|296147         0 PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|448082269|ref|XM_004195049.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|448082269|ref|XM_004195049.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "448082269")
            self.assertEqual(alignment.target.annotations["gis"], "448082269")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004195049")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004195049")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004195049.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 183)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 177)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "PFILSSHNWNAKTATISIPIIHKLIISNAVSREDLEQLLHALKEASNLALDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.55)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 35)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.64)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559304")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 62)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 55 aligned letters; 19 identities; 36 mismatches; 35 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 55:
        identities = 19,
        positives = 35,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 35)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|448082         0 CIVFSVNRREETPVFVM 17
                  0 |.....||.||...|.| 17
gi|296147         0 CVLYLPNRKEEIQPFAM 17
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[ 0, 17],
                              [ 0, 17]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|448082269|ref|XM_004195049.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|448082269|ref|XM_004195049.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "448082269")
            self.assertEqual(alignment.target.annotations["gis"], "448082269")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004195049")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004195049")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004195049.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 55)
            self.assertEqual(alignment.query.annotations["end"], 106)
            self.assertEqual(alignment.target.annotations["start"], 31)
            self.assertEqual(alignment.target.annotations["end"], 82)
            self.assertEqual(alignment.target.seq, "CIVFSVNRREETPVFVM")
            self.assertEqual(alignment.query.seq, "CVLYLPNRKEEIQPFAM")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 22.1)
            self.assertAlmostEqual(alignment.score, 42)
            self.assertEqual(alignment.shape, (2, 17))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.18)
            self.assertEqual(alignment.annotations["identical"], 7)
            self.assertEqual(alignment.annotations["mismatches"], 10)
            self.assertEqual(alignment.annotations["positives"], 11)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 64.71)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "559304")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 62)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 15)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 42.0; 17 aligned letters; 7 identities; 10 mismatches; 11 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 42.0,
    aligned = 17:
        identities = 7,
        positives = 11,
        mismatches = 10.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 17)
            self.assertEqual(counts.identities, 7)
            self.assertEqual(counts.mismatches, 10)
            self.assertEqual(counts.positives, 11)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|359487         0 VKDGAEHGILKLRSLSSPSEIAHNEDILRIFLMACEVRNVKLSVIGLSCLQKLISHDAVA
                  0 ........|..|....|..|.....|....|..||..||.|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|359487        60 PSALKEILSTLKDHAEMADE 80
                 60 .|.|.|||.........|.| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|359487908|ref|XM_003633625.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|359487908|ref|XM_003633625.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "359487908")
            self.assertEqual(alignment.target.annotations["gis"], "359487908")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003633625")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003633625")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003633625.1")
            self.assertEqual(alignment.target.annotations["length"], 5238)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHGILKLRSLSSPSEIAHNEDILRIFLMACEVRNVKLSVIGLSCLQKLISHDAVAPSALKEILSTLKDHAEMADE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 49.2)
            self.assertAlmostEqual(alignment.score, 101)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.50)
            self.assertEqual(alignment.annotations["identical"], 22)
            self.assertEqual(alignment.annotations["mismatches"], 58)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.50)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "29760")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Vitis vinifera protein MON2 homolog (LOC100264068), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Vitis vinifera protein MON2 homolog (LOC100264068), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 101.0; 80 aligned letters; 22 identities; 58 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 101.0,
    aligned = 80:
        identities = 22,
        positives = 42,
        mismatches = 58.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 22)
            self.assertEqual(counts.mismatches, 58)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302795         0 VKDAAEHAILKLRTITDPSQISRNDDVLRLYMLACDTRNVKLSILGLSCLQKLLAHDAVP
                  0 ...|....|..|..........|..|......|||..||.|...|...|||.|......|
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|302795        60 PLAFPQILETLQEHCEINDEI 81
                 60 ......||....|......|| 81
gi|296147        60 RSRLSEILDAFIEATHLAMEI 81
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  81],
                              [  0,  81]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302795299|ref|XM_002979367.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302795299|ref|XM_002979367.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302795299")
            self.assertEqual(alignment.target.annotations["gis"], "302795299")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002979367")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002979367")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002979367.1")
            self.assertEqual(alignment.target.annotations["length"], 5019)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(
                alignment.target.seq,
                "VKDAAEHAILKLRTITDPSQISRNDDVLRLYMLACDTRNVKLSILGLSCLQKLLAHDAVPPLAFPQILETLQEHCEINDEI",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 49.2)
            self.assertAlmostEqual(alignment.score, 101)
            self.assertEqual(alignment.shape, (2, 81))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.16)
            self.assertEqual(alignment.annotations["identical"], 22)
            self.assertEqual(alignment.annotations["mismatches"], 59)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 53.09)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "88036")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 101.0; 81 aligned letters; 22 identities; 59 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 101.0,
    aligned = 81:
        identities = 22,
        positives = 43,
        mismatches = 59.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 81)
            self.assertEqual(counts.identities, 22)
            self.assertEqual(counts.mismatches, 59)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302792         0 VKDAAEHAILKLRTVTDPSQIARNDDVLRLYMLACDTRNVKLSILGLSCLQKLLAHDAVP
                  0 ...|....|..|..|.......|..|......|||..||.|...|...|||.|......|
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|302792        60 PLAFPQILETLQEHCEINDEI 81
                 60 ......||....|......|| 81
gi|296147        60 RSRLSEILDAFIEATHLAMEI 81
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  81],
                              [  0,  81]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302792279|ref|XM_002977860.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302792279|ref|XM_002977860.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302792279")
            self.assertEqual(alignment.target.annotations["gis"], "302792279")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002977860")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002977860")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002977860.1")
            self.assertEqual(alignment.target.annotations["length"], 5197)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(
                alignment.target.seq,
                "VKDAAEHAILKLRTVTDPSQIARNDDVLRLYMLACDTRNVKLSILGLSCLQKLLAHDAVPPLAFPQILETLQEHCEINDEI",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 49.2)
            self.assertAlmostEqual(alignment.score, 101)
            self.assertEqual(alignment.shape, (2, 81))
            self.assertAlmostEqual(alignment.annotations["% identity"], 28.40)
            self.assertEqual(alignment.annotations["identical"], 23)
            self.assertEqual(alignment.annotations["mismatches"], 58)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 53.09)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "88036")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 101.0; 81 aligned letters; 23 identities; 58 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 101.0,
    aligned = 81:
        identities = 23,
        positives = 43,
        mismatches = 58.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 81)
            self.assertEqual(counts.identities, 23)
            self.assertEqual(counts.mismatches, 58)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|146416         0 AAPLVSTLASNNTKLVTISILAINRLAGTTAFSTATLGPLLDGLLEASHLAMDIQLR 57
                  0 |.|.|....|.|.|..|........|..........|...||...||.||||.|||. 57
gi|296147         0 ALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 57
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  57],
                              [  0,  57]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|146416588|ref|XM_001484214.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|146416588|ref|XM_001484214.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "146416588")
            self.assertEqual(alignment.target.annotations["gis"], "146416588")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001484214")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001484214")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001484214.1")
            self.assertEqual(alignment.target.annotations["length"], 1320)
            self.assertEqual(alignment.query.annotations["start"], 177)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 168)
            self.assertEqual(alignment.target.annotations["end"], 339)
            self.assertEqual(
                alignment.target.seq,
                "AAPLVSTLASNNTKLVTISILAINRLAGTTAFSTATLGPLLDGLLEASHLAMDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "ALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 5e-04)
            self.assertAlmostEqual(alignment.annotations["bit score"], 48.7)
            self.assertAlmostEqual(alignment.score, 100)
            self.assertEqual(alignment.shape, (2, 57))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.09)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 33)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.89)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "294746")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Meyerozyma guilliermondii ATCC 6260 hypothetical protein (PGUG_03645) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Meyerozyma guilliermondii ATCC 6260 hypothetical protein (PGUG_03645) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 49)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 49)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 100.0; 57 aligned letters; 20 identities; 37 mismatches; 33 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 100.0,
    aligned = 57:
        identities = 20,
        positives = 33,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 57)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 33)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|255542         0 VKDGAEHAILKLRSLSSPNEIAHNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVA
                  0 ........|..|....|..|.....|....|..||..|..|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|255542        60 PSALKEILSTLKDHAEMADE 80
                 60 .|.|.|||.........|.| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|255542393|ref|XM_002512214.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|255542393|ref|XM_002512214.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "255542393")
            self.assertEqual(alignment.target.annotations["gis"], "255542393")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002512214")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002512214")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002512214.1")
            self.assertEqual(alignment.target.annotations["length"], 4776)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSLSSPNEIAHNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVAPSALKEILSTLKDHAEMADE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.002)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.9)
            self.assertAlmostEqual(alignment.score, 96)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 26.25)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 59)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.50)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3988")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ricinus communis guanine nucleotide-exchange, putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ricinus communis guanine nucleotide-exchange, putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 96.0; 80 aligned letters; 21 identities; 59 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 96.0,
    aligned = 80:
        identities = 21,
        positives = 42,
        mismatches = 59.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 59)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470133         0 VKDGAEHAILKLRSLSSPGEIAQNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVA
                  0 ........|..|....|..|.....|....|..||..|..|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|470133        60 SSALHEILSTLKDHAEMADE 80
                 60 .|.|.|||.........|.| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470133344|ref|XM_004302479.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470133344|ref|XM_004302479.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470133344")
            self.assertEqual(alignment.target.annotations["gis"], "470133344")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004302479")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004302479")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004302479.1")
            self.assertEqual(alignment.target.annotations["length"], 5152)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSLSSPGEIAQNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVASSALHEILSTLKDHAEMADE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.002)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.4)
            self.assertAlmostEqual(alignment.score, 95)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 26.25)
            self.assertEqual(alignment.annotations["identical"], 21)
            self.assertEqual(alignment.annotations["mismatches"], 59)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 53.75)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "101020")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Fragaria vesca subsp. vesca protein MON2 homolog (LOC101302372), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Fragaria vesca subsp. vesca protein MON2 homolog (LOC101302372), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 95.0; 80 aligned letters; 21 identities; 59 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 95.0,
    aligned = 80:
        identities = 21,
        positives = 43,
        mismatches = 59.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 21)
            self.assertEqual(counts.mismatches, 59)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|356574         0 TVKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAV
                  0 |........|..|....|..|.....|....|..||..|..|.......|||.|......
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI

gi|356574        60 SPSALREIL 69
                 60 ..|.|.||| 69
gi|296147        60 PRSRLSEIL 69
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  69],
                              [  0,  69]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|356574903|ref|XM_003555535.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|356574903|ref|XM_003555535.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "356574903")
            self.assertEqual(alignment.target.annotations["gis"], "356574903")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003555535")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003555535")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003555535.1")
            self.assertEqual(alignment.target.annotations["length"], 4935)
            self.assertEqual(alignment.query.annotations["start"], 93)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 69)
            self.assertEqual(alignment.target.annotations["end"], 276)
            self.assertEqual(
                alignment.target.seq,
                "TVKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVSPSALREIL",
            )
            self.assertEqual(
                alignment.query.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.002)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.4)
            self.assertAlmostEqual(alignment.score, 95)
            self.assertEqual(alignment.shape, (2, 69))
            self.assertAlmostEqual(alignment.annotations["% identity"], 28.99)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 49)
            self.assertEqual(alignment.annotations["positives"], 39)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 56.52)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3847")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Glycine max protein MON2 homolog (LOC100777257), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Glycine max protein MON2 homolog (LOC100777257), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 59)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 59)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 95.0; 69 aligned letters; 20 identities; 49 mismatches; 39 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 95.0,
    aligned = 69:
        identities = 20,
        positives = 39,
        mismatches = 49.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 69)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 49)
            self.assertEqual(counts.positives, 39)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|334187         0 VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVE
                  0 ........|..|....|...|....|....|..||..||.|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|334187        60 PSSLKEILYTLKDHSEMAEE 80
                 60 .|.|.|||.........|.| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|334187990|ref|NM_001203485.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|334187990|ref|NM_001203485.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "334187990")
            self.assertEqual(alignment.target.annotations["gis"], "334187990")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001203485")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001203485")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001203485.1")
            self.assertEqual(alignment.target.annotations["length"], 5026)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVEPSSLKEILYTLKDHSEMAEE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.002)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.4)
            self.assertAlmostEqual(alignment.score, 95)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.50)
            self.assertEqual(alignment.annotations["identical"], 22)
            self.assertEqual(alignment.annotations["mismatches"], 58)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.50)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3702")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Arabidopsis thaliana armadillo/beta-catenin-like repeat-containing protein (AT5G27970) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Arabidopsis thaliana armadillo/beta-catenin-like repeat-containing protein (AT5G27970) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 95.0; 80 aligned letters; 22 identities; 58 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 95.0,
    aligned = 80:
        identities = 22,
        positives = 42,
        mismatches = 58.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 22)
            self.assertEqual(counts.mismatches, 58)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|334187         0 VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVE
                  0 ........|..|....|...|....|....|..||..||.|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|334187        60 PSSLKEILYTLKDAKQLS 78
                 60 .|.|.|||.....|..|. 78
gi|296147        60 RSRLSEILDAFIEATHLA 78
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  78],
                              [  0,  78]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|334187988|ref|NM_122680.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|334187988|ref|NM_122680.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "334187988")
            self.assertEqual(alignment.target.annotations["gis"], "334187988")
            self.assertEqual(alignment.target.annotations["acc."], "NM_122680")
            self.assertEqual(alignment.target.annotations["accs."], "NM_122680")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_122680.3")
            self.assertEqual(alignment.target.annotations["length"], 5132)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 330)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 306)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVEPSSLKEILYTLKDAKQLS",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.002)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.4)
            self.assertAlmostEqual(alignment.score, 95)
            self.assertEqual(alignment.shape, (2, 78))
            self.assertAlmostEqual(alignment.annotations["% identity"], 28.21)
            self.assertEqual(alignment.annotations["identical"], 22)
            self.assertEqual(alignment.annotations["mismatches"], 56)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.56)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3702")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Arabidopsis thaliana armadillo/beta-catenin-like repeat-containing protein (AT5G27970) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Arabidopsis thaliana armadillo/beta-catenin-like repeat-containing protein (AT5G27970) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 67)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 67)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 95.0; 78 aligned letters; 22 identities; 56 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 95.0,
    aligned = 78:
        identities = 22,
        positives = 41,
        mismatches = 56.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 78)
            self.assertEqual(counts.identities, 22)
            self.assertEqual(counts.mismatches, 56)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|356535         0 VKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSIIGLSCLQKLISHDAVS
                  0 ........|..|....|..|.....|....|..||..|..|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|356535        60 PSALTEILSTLKDA 74
                 60 .|.|.|||.....| 74
gi|296147        60 RSRLSEILDAFIEA 74
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  74],
                              [  0,  74]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|356535140|ref|XM_003536059.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|356535140|ref|XM_003536059.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "356535140")
            self.assertEqual(alignment.target.annotations["gis"], "356535140")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003536059")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003536059")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003536059.1")
            self.assertEqual(alignment.target.annotations["length"], 5612)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 318)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 294)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSIIGLSCLQKLISHDAVSPSALTEILSTLKDA",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEA",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.003)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.0)
            self.assertAlmostEqual(alignment.score, 94)
            self.assertEqual(alignment.shape, (2, 74))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.03)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 54)
            self.assertEqual(alignment.annotations["positives"], 41)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3847")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Glycine max protein MON2 homolog, transcript variant 2 (LOC100818893), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Glycine max protein MON2 homolog, transcript variant 2 (LOC100818893), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 63)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 63)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 94.0; 74 aligned letters; 20 identities; 54 mismatches; 41 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 94.0,
    aligned = 74:
        identities = 20,
        positives = 41,
        mismatches = 54.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 74)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 54)
            self.assertEqual(counts.positives, 41)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296414         0 ELSGRPQFIHPFLIACSTRNAKFSTIGVVCLQRLIVSQGLAKVCRQDIL 49
                  0 ||...|.|..||..||..||||..|....|||.|.............|| 49
gi|296147         0 ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL 49
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  49],
                              [  0,  49]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296414539|ref|XM_002836911.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|296414539|ref|XM_002836911.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "296414539")
            self.assertEqual(alignment.target.annotations["gis"], "296414539")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002836911")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002836911")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002836911.1")
            self.assertEqual(alignment.target.annotations["length"], 5004)
            self.assertEqual(alignment.query.annotations["start"], 153)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 147)
            self.assertEqual(alignment.target.annotations["end"], 294)
            self.assertEqual(
                alignment.target.seq,
                "ELSGRPQFIHPFLIACSTRNAKFSTIGVVCLQRLIVSQGLAKVCRQDIL",
            )
            self.assertEqual(
                alignment.query.seq, "ELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.003)
            self.assertAlmostEqual(alignment.annotations["bit score"], 46.0)
            self.assertAlmostEqual(alignment.score, 94)
            self.assertEqual(alignment.shape, (2, 49))
            self.assertAlmostEqual(alignment.annotations["% identity"], 38.78)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 30)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.14)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "656061")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Tuber melanosporum Mel28 hypothetical protein (GSTUM_00003289001) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Tuber melanosporum Mel28 hypothetical protein (GSTUM_00003289001) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 42)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 42)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 94.0; 49 aligned letters; 19 identities; 30 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 94.0,
    aligned = 49:
        identities = 19,
        positives = 28,
        mismatches = 30.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 49)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 30)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|297597         0 SVKDAAEHAILKLRSLSSPMEIAQNEDILRMFLVACSVKSVKLSVIGLSCLQKLISHDAV
                  0 ....|....|..|....|..|.....|....|..||.....|.......|||.|......
gi|296147         0 TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSI

gi|297597        60 ASSALKDILTTLKDHAEMTDEI 82
                 60 ..|.|..||...........|| 82
gi|296147        60 PRSRLSEILDAFIEATHLAMEI 82
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  82],
                              [  0,  82]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|297597693|ref|NM_001050929.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|297597693|ref|NM_001050929.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "297597693")
            self.assertEqual(alignment.target.annotations["gis"], "297597693")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001050929")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001050929")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001050929.2")
            self.assertEqual(alignment.target.annotations["length"], 3804)
            self.assertEqual(alignment.query.annotations["start"], 93)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 69)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(
                alignment.target.seq,
                "SVKDAAEHAILKLRSLSSPMEIAQNEDILRMFLVACSVKSVKLSVIGLSCLQKLISHDAVASSALKDILTTLKDHAEMTDEI",
            )
            self.assertEqual(
                alignment.query.seq,
                "TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.004)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.5)
            self.assertAlmostEqual(alignment.score, 93)
            self.assertEqual(alignment.shape, (2, 82))
            self.assertAlmostEqual(alignment.annotations["% identity"], 24.39)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 62)
            self.assertEqual(alignment.annotations["positives"], 45)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 54.88)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "39947")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Oryza sativa Japonica Group Os01g0772700 (Os01g0772700) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Oryza sativa Japonica Group Os01g0772700 (Os01g0772700) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 70)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 70)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 93.0; 82 aligned letters; 20 identities; 62 mismatches; 45 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 93.0,
    aligned = 82:
        identities = 20,
        positives = 45,
        mismatches = 62.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 82)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 62)
            self.assertEqual(counts.positives, 45)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|448086         0 PFILSSHNWNAKTATISIPIIHKLIISNAVSREDLEQLLHALKEASNLALDIQLR 55
                  0 ||.|.....|||..|........|.......|..|...|.|..||..||..|||. 55
gi|296147         0 PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|448086792|ref|XM_004196143.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|448086792|ref|XM_004196143.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "448086792")
            self.assertEqual(alignment.target.annotations["gis"], "448086792")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004196143")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004196143")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004196143.1")
            self.assertEqual(alignment.target.annotations["length"], 4794)
            self.assertEqual(alignment.query.annotations["start"], 183)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 177)
            self.assertEqual(alignment.target.annotations["end"], 342)
            self.assertEqual(
                alignment.target.seq,
                "PFILSSHNWNAKTATISIPIIHKLIISNAVSREDLEQLLHALKEASNLALDIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.55)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 36)
            self.assertEqual(alignment.annotations["positives"], 35)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.64)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "559304")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Millerozyma farinosa CBS 7064 hypothetical protein (Piso0_005640) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 55 aligned letters; 19 identities; 36 mismatches; 35 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 55:
        identities = 19,
        positives = 35,
        mismatches = 36.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 36)
            self.assertEqual(counts.positives, 35)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|403176         0 DIFRPISMACATKNAKVVVIALGSLQRLIAMDAVPSCKIPQIVNLLSTVLPLGVEIQLR
                  0 |...|...||...|||....|...||.|......|......|.........|..||||.
gi|296147         0 DFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK

gi|403176        59
                 59
gi|296147        59
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  59],
                              [  0,  59]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|403176154|ref|XM_003334821.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|403176154|ref|XM_003334821.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "403176154")
            self.assertEqual(alignment.target.annotations["gis"], "403176154")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003334821")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003334821")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003334821.2")
            self.assertEqual(alignment.target.annotations["length"], 5427)
            self.assertEqual(alignment.query.annotations["start"], 171)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 186)
            self.assertEqual(alignment.target.annotations["end"], 363)
            self.assertEqual(
                alignment.target.seq,
                "DIFRPISMACATKNAKVVVIALGSLQRLIAMDAVPSCKIPQIVNLLSTVLPLGVEIQLR",
            )
            self.assertEqual(
                alignment.query.seq,
                "DFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 59))
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.51)
            self.assertEqual(alignment.annotations["identical"], 18)
            self.assertEqual(alignment.annotations["mismatches"], 41)
            self.assertEqual(alignment.annotations["positives"], 34)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.63)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "418459")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Puccinia graminis f. sp. tritici CRL 75-36-700-3 hypothetical protein (PGTG_16037), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Puccinia graminis f. sp. tritici CRL 75-36-700-3 hypothetical protein (PGTG_16037), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 51)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 51)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 59 aligned letters; 18 identities; 41 mismatches; 34 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 59:
        identities = 18,
        positives = 34,
        mismatches = 41.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 59)
            self.assertEqual(counts.identities, 18)
            self.assertEqual(counts.mismatches, 41)
            self.assertEqual(counts.positives, 34)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|356535         0 VKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSIIGLSCLQKLISHDAVS
                  0 ........|..|....|..|.....|....|..||..|..|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|356535        60 PSALTEILSTLKDHAEMVDE 80
                 60 .|.|.|||...........| 80
gi|296147        60 RSRLSEILDAFIEATHLAME 80
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  80],
                              [  0,  80]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|356535138|ref|XM_003536058.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|356535138|ref|XM_003536058.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "356535138")
            self.assertEqual(alignment.target.annotations["gis"], "356535138")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003536058")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003536058")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003536058.1")
            self.assertEqual(alignment.target.annotations["length"], 5530)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 336)
            self.assertEqual(alignment.target.annotations["start"], 152)
            self.assertEqual(alignment.target.annotations["end"], 392)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRTLSSPSEIAHNDDILRIFLMACEVRTVKLSIIGLSCLQKLISHDAVSPSALTEILSTLKDHAEMVDE",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAME",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.006)
            self.assertAlmostEqual(alignment.annotations["bit score"], 45.1)
            self.assertAlmostEqual(alignment.score, 92)
            self.assertEqual(alignment.shape, (2, 80))
            self.assertAlmostEqual(alignment.annotations["% identity"], 25.00)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 60)
            self.assertEqual(alignment.annotations["positives"], 42)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.50)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "3847")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Glycine max protein MON2 homolog, transcript variant 1 (LOC100818893), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Glycine max protein MON2 homolog, transcript variant 1 (LOC100818893), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 92.0; 80 aligned letters; 20 identities; 60 mismatches; 42 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 92.0,
    aligned = 80:
        identities = 20,
        positives = 42,
        mismatches = 60.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 80)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 60)
            self.assertEqual(counts.positives, 42)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|297808         0 VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVE
                  0 ........|..|....|...|....|....|..||..||.|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|297808        60 PSSLKEIL 68
                 60 .|.|.||| 68
gi|296147        60 RSRLSEIL 68
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  68],
                              [  0,  68]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|297808820|ref|XM_002872248.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|297808820|ref|XM_002872248.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "297808820")
            self.assertEqual(alignment.target.annotations["gis"], "297808820")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002872248")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002872248")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002872248.1")
            self.assertEqual(alignment.target.annotations["length"], 4854)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 276)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSSSSASDLSSNEDILRIFLMACGVRNTKLSVIGLSCLQKLISHDAVEPSSLKEIL",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.008)
            self.assertAlmostEqual(alignment.annotations["bit score"], 44.6)
            self.assertAlmostEqual(alignment.score, 91)
            self.assertEqual(alignment.shape, (2, 68))
            self.assertAlmostEqual(alignment.annotations["% identity"], 29.41)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 48)
            self.assertEqual(alignment.annotations["positives"], 37)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 54.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "81972")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Arabidopsis lyrata subsp. lyrata binding protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Arabidopsis lyrata subsp. lyrata binding protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 58)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 58)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 91.0; 68 aligned letters; 20 identities; 48 mismatches; 37 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 91.0,
    aligned = 68:
        identities = 20,
        positives = 37,
        mismatches = 48.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 68)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 48)
            self.assertEqual(counts.positives, 37)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|242054         0 VKDAAEHAVLKLRSLSGPSEIAQNEDILRMFLMACSVKSVKLSVIGLSCLQKLISHGAVA
                  0 ...|.......|.......|.....|....|..||.....|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|242054        60 SSALKEILATLKDHAEMTDEI 81
                 60 .|.|.|||...........|| 81
gi|296147        60 RSRLSEILDAFIEATHLAMEI 81
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  81],
                              [  0,  81]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|242054552|ref|XM_002456377.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|242054552|ref|XM_002456377.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "242054552")
            self.assertEqual(alignment.target.annotations["gis"], "242054552")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002456377")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002456377")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002456377.1")
            self.assertEqual(alignment.target.annotations["length"], 414)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(
                alignment.target.seq,
                "VKDAAEHAVLKLRSLSGPSEIAQNEDILRMFLMACSVKSVKLSVIGLSCLQKLISHGAVASSALKEILATLKDHAEMTDEI",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.008)
            self.assertAlmostEqual(alignment.annotations["bit score"], 44.6)
            self.assertAlmostEqual(alignment.score, 91)
            self.assertEqual(alignment.shape, (2, 81))
            self.assertAlmostEqual(alignment.annotations["% identity"], 23.46)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 62)
            self.assertEqual(alignment.annotations["positives"], 43)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 53.09)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "4558")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Sorghum bicolor hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Sorghum bicolor hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 69)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 69)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 91.0; 81 aligned letters; 19 identities; 62 mismatches; 43 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 91.0,
    aligned = 81:
        identities = 19,
        positives = 43,
        mismatches = 62.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 81)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 62)
            self.assertEqual(counts.positives, 43)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|224125         0 VKDGAEHAILKLRSLSSPSEIADNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVA
                  0 ........|..|....|..|.....|....|..||..|..|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|224125        60 PSALKEIL 68
                 60 .|.|.||| 68
gi|296147        60 RSRLSEIL 68
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  68],
                              [  0,  68]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|224125555|ref|XM_002319579.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|224125555|ref|XM_002319579.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "224125555")
            self.assertEqual(alignment.target.annotations["gis"], "224125555")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002319579")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002319579")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002319579.1")
            self.assertEqual(alignment.target.annotations["length"], 4914)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 276)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRSLSSPSEIADNEDILRIFLMACEVRTVKLSVIGLSCLQKLISHDAVAPSALKEIL",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.015)
            self.assertAlmostEqual(alignment.annotations["bit score"], 43.7)
            self.assertAlmostEqual(alignment.score, 89)
            self.assertEqual(alignment.shape, (2, 68))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.94)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 49)
            self.assertEqual(alignment.annotations["positives"], 38)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 55.88)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3694")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Populus trichocarpa predicted protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Populus trichocarpa predicted protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 58)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 58)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 89.0; 68 aligned letters; 19 identities; 49 mismatches; 38 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 89.0,
    aligned = 68:
        identities = 19,
        positives = 38,
        mismatches = 49.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 68)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 49)
            self.assertEqual(counts.positives, 38)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|357131         0 VKDAAEHATLKLRSLSNPSEIAQNGDILRMFLMACSVKSVKLSAIGLSCLQKLISHDAVA
                  0 ...|.......|.......|.....|....|..||.....|.......|||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|357131        60 SSALKEIL 68
                 60 .|.|.||| 68
gi|296147        60 RSRLSEIL 68
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  68],
                              [  0,  68]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|357131062|ref|XR_138050.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|357131062|ref|XR_138050.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "357131062")
            self.assertEqual(alignment.target.annotations["gis"], "357131062")
            self.assertEqual(alignment.target.annotations["acc."], "XR_138050")
            self.assertEqual(alignment.target.annotations["accs."], "XR_138050")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XR_138050.1")
            self.assertEqual(alignment.target.annotations["length"], 3794)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 276)
            self.assertEqual(
                alignment.target.seq,
                "VKDAAEHATLKLRSLSNPSEIAQNGDILRMFLMACSVKSVKLSAIGLSCLQKLISHDAVASSALKEIL",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.054)
            self.assertAlmostEqual(alignment.annotations["bit score"], 41.8)
            self.assertAlmostEqual(alignment.score, 85)
            self.assertEqual(alignment.shape, (2, 68))
            self.assertAlmostEqual(alignment.annotations["% identity"], 25.00)
            self.assertEqual(alignment.annotations["identical"], 17)
            self.assertEqual(alignment.annotations["mismatches"], 51)
            self.assertEqual(alignment.annotations["positives"], 39)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 57.35)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "15368")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Brachypodium distachyon uncharacterized LOC100838086 (LOC100838086), miscRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Brachypodium distachyon uncharacterized LOC100838086 (LOC100838086), miscRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 58)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 58)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 85.0; 68 aligned letters; 17 identities; 51 mismatches; 39 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 85.0,
    aligned = 68:
        identities = 17,
        positives = 39,
        mismatches = 51.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 68)
            self.assertEqual(counts.identities, 17)
            self.assertEqual(counts.mismatches, 51)
            self.assertEqual(counts.positives, 39)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|403290         0 TLEVSCLQGLHTSPSLEDQGVSQITNAFNMVVHLSNTLELQ 41
                  0 ||...|||||.|.||......|.|..||....||.....|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|403290914|ref|XM_003936502.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|403290914|ref|XM_003936502.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "403290914")
            self.assertEqual(alignment.target.annotations["gis"], "403290914")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003936502")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003936502")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003936502.1")
            self.assertEqual(alignment.target.annotations["length"], 7255)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6675)
            self.assertEqual(alignment.target.annotations["end"], 6552)
            self.assertEqual(
                alignment.target.seq, "TLEVSCLQGLHTSPSLEDQGVSQITNAFNMVVHLSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.14)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.5)
            self.assertAlmostEqual(alignment.score, 82)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.46)
            self.assertEqual(alignment.annotations["identical"], 17)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "39432")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Saimiri boliviensis boliviensis Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Saimiri boliviensis boliviensis Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 82.0; 41 aligned letters; 17 identities; 24 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 82.0,
    aligned = 41:
        identities = 17,
        positives = 26,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 17)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|297707         0 TLGVSCLQGLHTLPSLEDKGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||.|.||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|297707079|ref|XM_002830297.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|297707079|ref|XM_002830297.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "297707079")
            self.assertEqual(alignment.target.annotations["gis"], "297707079")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002830297")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002830297")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002830297.1")
            self.assertEqual(alignment.target.annotations["length"], 8045)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6177)
            self.assertEqual(alignment.target.annotations["end"], 6054)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHTLPSLEDKGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.14)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.5)
            self.assertAlmostEqual(alignment.score, 82)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 39.02)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 25)
            self.assertEqual(alignment.annotations["positives"], 27)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.85)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9601")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pongo abelii Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pongo abelii Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 82.0; 41 aligned letters; 16 identities; 25 mismatches; 27 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 82.0,
    aligned = 41:
        identities = 16,
        positives = 27,
        mismatches = 25.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 25)
            self.assertEqual(counts.positives, 27)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|254567         0 ASIDMIRSFKQRVPIQELVKFESFVDPFLLSIQTRSLKLVNTGLACLQKLIIESAIADTK
                  0 ||...|...|......||.....|..||.|..|.|..|.......|||.|.....|....
gi|296147         0 ASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSR

gi|254567        60 LESLVNSLL 69
                 60 |........ 69
gi|296147        60 LSEILDAFI 69
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  69],
                              [  0,  69]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|254567673|ref|XM_002490902.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|254567673|ref|XM_002490902.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "254567673")
            self.assertEqual(alignment.target.annotations["gis"], "254567673")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002490902")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002490902")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002490902.1")
            self.assertEqual(alignment.target.annotations["length"], 4647)
            self.assertEqual(alignment.query.annotations["start"], 105)
            self.assertEqual(alignment.query.annotations["end"], 312)
            self.assertEqual(alignment.target.annotations["start"], 87)
            self.assertEqual(alignment.target.annotations["end"], 294)
            self.assertEqual(
                alignment.target.seq,
                "ASIDMIRSFKQRVPIQELVKFESFVDPFLLSIQTRSLKLVNTGLACLQKLIIESAIADTKLESLVNSLL",
            )
            self.assertEqual(
                alignment.query.seq,
                "ASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.19)
            self.assertAlmostEqual(alignment.annotations["bit score"], 40.0)
            self.assertAlmostEqual(alignment.score, 81)
            self.assertEqual(alignment.shape, (2, 69))
            self.assertAlmostEqual(alignment.annotations["% identity"], 27.54)
            self.assertEqual(alignment.annotations["identical"], 19)
            self.assertEqual(alignment.annotations["mismatches"], 50)
            self.assertEqual(alignment.annotations["positives"], 36)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 52.17)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "644223")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pichia pastoris GS115 Peripheral membrane protein with a role in endocytosis and vacuole integrity, interacts with Arl1p a (PAS_chr2-1_0066) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pichia pastoris GS115 Peripheral membrane protein with a role in endocytosis and vacuole integrity, interacts with Arl1p a (PAS_chr2-1_0066) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 59)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 59)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 81.0; 69 aligned letters; 19 identities; 50 mismatches; 36 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 81.0,
    aligned = 69:
        identities = 19,
        positives = 36,
        mismatches = 50.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 69)
            self.assertEqual(counts.identities, 19)
            self.assertEqual(counts.mismatches, 50)
            self.assertEqual(counts.positives, 36)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|302772         0 MLTCKTRNIKLSVLGLSCLQKLLAHDAIPPLAVPQILEILQEHSEIHYEV 50
                  0 .|.|..||.|...|...|||.|.....||......||....|......|. 50
gi|296147         0 VLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI 50
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  50],
                              [  0,  50]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|302772536|ref|XM_002969640.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|302772536|ref|XM_002969640.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "302772536")
            self.assertEqual(alignment.target.annotations["gis"], "302772536")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002969640")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002969640")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002969640.1")
            self.assertEqual(alignment.target.annotations["length"], 399)
            self.assertEqual(alignment.query.annotations["start"], 189)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 0)
            self.assertEqual(alignment.target.annotations["end"], 150)
            self.assertEqual(
                alignment.target.seq,
                "MLTCKTRNIKLSVLGLSCLQKLLAHDAIPPLAVPQILEILQEHSEIHYEV",
            )
            self.assertEqual(
                alignment.query.seq,
                "VLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEI",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.27)
            self.assertAlmostEqual(alignment.annotations["bit score"], 39.6)
            self.assertAlmostEqual(alignment.score, 80)
            self.assertEqual(alignment.shape, (2, 50))
            self.assertAlmostEqual(alignment.annotations["% identity"], 32.00)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 34)
            self.assertEqual(alignment.annotations["positives"], 29)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 58.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "88036")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Selaginella moellendorffii hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 43)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 43)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 80.0; 50 aligned letters; 16 identities; 34 mismatches; 29 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 80.0,
    aligned = 50:
        identities = 16,
        positives = 29,
        mismatches = 34.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 50)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 34)
            self.assertEqual(counts.positives, 29)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|189235         0 YFLPFELACQSRSARIVVTALDCLQKL 27
                  0 ..|||.||||||.|.....|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|189235995|ref|XM_967692.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|189235995|ref|XM_967692.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "189235995")
            self.assertEqual(alignment.target.annotations["gis"], "189235995")
            self.assertEqual(alignment.target.annotations["acc."], "XM_967692")
            self.assertEqual(alignment.target.annotations["accs."], "XM_967692")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_967692.2")
            self.assertEqual(alignment.target.annotations["length"], 5169)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 231)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRSARIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.27)
            self.assertAlmostEqual(alignment.annotations["bit score"], 39.6)
            self.assertAlmostEqual(alignment.score, 80)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 55.56)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 12)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7070")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Tribolium castaneum similar to AGAP008906-PA (LOC661541), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Tribolium castaneum similar to AGAP008906-PA (LOC661541), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 80.0; 27 aligned letters; 15 identities; 12 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 80.0,
    aligned = 27:
        identities = 15,
        positives = 20,
        mismatches = 12.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 12)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|238586         0 MACATKNAKVVAISLGSLQRLIALKAVPQSDVPLIIKTMSDSMSQGVDIQLK 52
                  0 .||...|||........||.|......|.|....|.............|||| 52
gi|296147         0 LACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 52
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  52],
                              [  0,  52]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|238586708|ref|XM_002391211.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|238586708|ref|XM_002391211.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "238586708")
            self.assertEqual(alignment.target.annotations["gis"], "238586708")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002391211")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002391211")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002391211.1")
            self.assertEqual(alignment.target.annotations["length"], 1557)
            self.assertEqual(alignment.query.annotations["start"], 192)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 0)
            self.assertEqual(alignment.target.annotations["end"], 156)
            self.assertEqual(
                alignment.target.seq,
                "MACATKNAKVVAISLGSLQRLIALKAVPQSDVPLIIKTMSDSMSQGVDIQLK",
            )
            self.assertEqual(
                alignment.query.seq,
                "LACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.50)
            self.assertAlmostEqual(alignment.annotations["bit score"], 38.6)
            self.assertAlmostEqual(alignment.score, 78)
            self.assertEqual(alignment.shape, (2, 52))
            self.assertAlmostEqual(alignment.annotations["% identity"], 28.85)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 37)
            self.assertEqual(alignment.annotations["positives"], 32)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 61.54)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "554373")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Moniliophthora perniciosa FA553 hypothetical protein (MPER_09344) mRNA, partial cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Moniliophthora perniciosa FA553 hypothetical protein (MPER_09344) mRNA, partial cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 45)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 45)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 78.0; 52 aligned letters; 15 identities; 37 mismatches; 32 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 78.0,
    aligned = 52:
        identities = 15,
        positives = 32,
        mismatches = 37.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 52)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 37)
            self.assertEqual(counts.positives, 32)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|827342         0 TLGVSCLQGLHILPSLEDEEVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|82734234|ref|NM_020336.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|82734234|ref|NM_020336.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "82734234")
            self.assertEqual(alignment.target.annotations["gis"], "82734234")
            self.assertEqual(alignment.target.annotations["acc."], "NM_020336")
            self.assertEqual(alignment.target.annotations["accs."], "NM_020336")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_020336.2")
            self.assertEqual(alignment.target.annotations["length"], 8636)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6902)
            self.assertEqual(alignment.target.annotations["end"], 6779)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEEVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.50)
            self.assertAlmostEqual(alignment.annotations["bit score"], 38.6)
            self.assertAlmostEqual(alignment.score, 78)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9606")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Homo sapiens Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Homo sapiens Ral GTPase activating protein, beta subunit (non-catalytic) (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 78.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 78.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|391342         0 FMAPFELACQSKSPRLTVIALDCVQKL 27
                  0 |..||.|||||.....|..|..|.|.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|391342729|ref|XM_003745620.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|391342729|ref|XM_003745620.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "391342729")
            self.assertEqual(alignment.target.annotations["gis"], "391342729")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003745620")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003745620")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003745620.1")
            self.assertEqual(alignment.target.annotations["length"], 4662)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 210)
            self.assertEqual(alignment.target.annotations["end"], 291)
            self.assertEqual(alignment.target.seq, "FMAPFELACQSKSPRLTVIALDCVQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.69)
            self.assertAlmostEqual(alignment.annotations["bit score"], 38.2)
            self.assertAlmostEqual(alignment.score, 77)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "34638")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Metaseiulus occidentalis brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100907146), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Metaseiulus occidentalis brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100907146), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 77.0; 27 aligned letters; 13 identities; 14 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 77.0,
    aligned = 27:
        identities = 13,
        positives = 20,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|291235         0 YFLPFELACQSKSARIVNTALDCLQKL 27
                  0 ..|||.|||||..|.....|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|291235727|ref|XM_002737750.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|291235727|ref|XM_002737750.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "291235727")
            self.assertEqual(alignment.target.annotations["gis"], "291235727")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002737750")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002737750")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002737750.1")
            self.assertEqual(alignment.target.annotations["length"], 4743)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 198)
            self.assertEqual(alignment.target.annotations["end"], 279)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSARIVNTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.69)
            self.assertAlmostEqual(alignment.annotations["bit score"], 38.2)
            self.assertAlmostEqual(alignment.score, 77)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 51.85)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "10224")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Saccoglossus kowalevskii ADP-ribosylation factor guanine nucleotide-exchange factor 1(brefeldin A-inhibited)-like (LOC100366823), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Saccoglossus kowalevskii ADP-ribosylation factor guanine nucleotide-exchange factor 1(brefeldin A-inhibited)-like (LOC100366823), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 77.0; 27 aligned letters; 14 identities; 13 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 77.0,
    aligned = 27:
        identities = 14,
        positives = 20,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|330938         0 ISAMSPVPVLARVRLSDVDDAYFRISHVVSDL 32
                  0 ....|.||...|.|||...||.....|..... 32
gi|296147         0 LQGLSTVPSIPRSRLSEILDAFIEATHLAMEI 32
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  32],
                              [  0,  32]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|330938727|ref|XM_003305716.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|330938727|ref|XM_003305716.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "330938727")
            self.assertEqual(alignment.target.annotations["gis"], "330938727")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003305716")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003305716")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003305716.1")
            self.assertEqual(alignment.target.annotations["length"], 459)
            self.assertEqual(alignment.query.annotations["start"], 243)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 164)
            self.assertEqual(alignment.target.annotations["end"], 68)
            self.assertEqual(alignment.target.seq, "ISAMSPVPVLARVRLSDVDDAYFRISHVVSDL")
            self.assertEqual(alignment.query.seq, "LQGLSTVPSIPRSRLSEILDAFIEATHLAMEI")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.77)
            self.assertAlmostEqual(alignment.annotations["bit score"], 29.9)
            self.assertAlmostEqual(alignment.score, 59)
            self.assertEqual(alignment.shape, (2, 32))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.25)
            self.assertEqual(alignment.annotations["identical"], 10)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.50)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "861557")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pyrenophora teres f. teres 0-1 hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pyrenophora teres f. teres 0-1 hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 42)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 27)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 59.0; 32 aligned letters; 10 identities; 22 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 59.0,
    aligned = 32:
        identities = 10,
        positives = 20,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 32)
            self.assertEqual(counts.identities, 10)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|330938         0 SLPVIIRTHSLPQLERH 17
                  0 |.....|.||...|||| 17
gi|296147         0 SIEILKRVHSFEELERH 17
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  17],
                              [  0,  17]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|330938727|ref|XM_003305716.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|330938727|ref|XM_003305716.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "330938727")
            self.assertEqual(alignment.target.annotations["gis"], "330938727")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003305716")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003305716")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003305716.1")
            self.assertEqual(alignment.target.annotations["length"], 459)
            self.assertEqual(alignment.query.annotations["start"], 117)
            self.assertEqual(alignment.query.annotations["end"], 168)
            self.assertEqual(alignment.target.annotations["start"], 447)
            self.assertEqual(alignment.target.annotations["end"], 396)
            self.assertEqual(alignment.target.seq, "SLPVIIRTHSLPQLERH")
            self.assertEqual(alignment.query.seq, "SIEILKRVHSFEELERH")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.77)
            self.assertAlmostEqual(alignment.annotations["bit score"], 24.4)
            self.assertAlmostEqual(alignment.score, 47)
            self.assertEqual(alignment.shape, (2, 17))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.06)
            self.assertEqual(alignment.annotations["identical"], 8)
            self.assertEqual(alignment.annotations["mismatches"], 9)
            self.assertEqual(alignment.annotations["positives"], 12)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.59)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "861557")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pyrenophora teres f. teres 0-1 hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pyrenophora teres f. teres 0-1 hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 42)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 15)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 47.0; 17 aligned letters; 8 identities; 9 mismatches; 12 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 47.0,
    aligned = 17:
        identities = 8,
        positives = 12,
        mismatches = 9.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 17)
            self.assertEqual(counts.identities, 8)
            self.assertEqual(counts.mismatches, 9)
            self.assertEqual(counts.positives, 12)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|397511         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|397511126|ref|XM_003825883.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|397511126|ref|XM_003825883.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "397511126")
            self.assertEqual(alignment.target.annotations["gis"], "397511126")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003825883")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003825883")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003825883.1")
            self.assertEqual(alignment.target.annotations["length"], 8056)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6171)
            self.assertEqual(alignment.target.annotations["end"], 6048)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9597")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan paniscus Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan paniscus Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|397511         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|397511124|ref|XM_003825882.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|397511124|ref|XM_003825882.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "397511124")
            self.assertEqual(alignment.target.annotations["gis"], "397511124")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003825882")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003825882")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003825882.1")
            self.assertEqual(alignment.target.annotations["length"], 8831)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6946)
            self.assertEqual(alignment.target.annotations["end"], 6823)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9597")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan paniscus Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan paniscus Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|390362         0 LPFELACQSKSARIVNTALDCLQKL 25
                  0 |||.|||||..|.....|..|||.| 25
gi|296147         0 LPFVLACQSRNAKMTTLAMQCLQGL 25
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  25],
                              [  0,  25]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|390362724|ref|XR_025702.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|390362724|ref|XR_025702.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "390362724")
            self.assertEqual(alignment.target.annotations["gis"], "390362724")
            self.assertEqual(alignment.target.annotations["acc."], "XR_025702")
            self.assertEqual(alignment.target.annotations["accs."], "XR_025702")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XR_025702.2")
            self.assertEqual(alignment.target.annotations["length"], 5049)
            self.assertEqual(alignment.query.annotations["start"], 180)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 318)
            self.assertEqual(alignment.target.seq, "LPFELACQSKSARIVNTALDCLQKL")
            self.assertEqual(alignment.query.seq, "LPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 25))
            self.assertAlmostEqual(alignment.annotations["% identity"], 56.00)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 11)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 76.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7668")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Strongylocentrotus purpuratus brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC754128), misc_RNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Strongylocentrotus purpuratus brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC754128), misc_RNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 21)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 21)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 25 aligned letters; 14 identities; 11 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 25:
        identities = 14,
        positives = 19,
        mismatches = 11.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 25)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 11)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|390341         0 LPFELACQSKSARIVNTALDCLQKL 25
                  0 |||.|||||..|.....|..|||.| 25
gi|296147         0 LPFVLACQSRNAKMTTLAMQCLQGL 25
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  25],
                              [  0,  25]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|390341406|ref|XR_143615.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|390341406|ref|XR_143615.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "390341406")
            self.assertEqual(alignment.target.annotations["gis"], "390341406")
            self.assertEqual(alignment.target.annotations["acc."], "XR_143615")
            self.assertEqual(alignment.target.annotations["accs."], "XR_143615")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XR_143615.1")
            self.assertEqual(alignment.target.annotations["length"], 4439)
            self.assertEqual(alignment.query.annotations["start"], 180)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 791)
            self.assertEqual(alignment.target.annotations["end"], 866)
            self.assertEqual(alignment.target.seq, "LPFELACQSKSARIVNTALDCLQKL")
            self.assertEqual(alignment.query.seq, "LPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 25))
            self.assertAlmostEqual(alignment.annotations["% identity"], 56.00)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 11)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 76.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "7668")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Strongylocentrotus purpuratus brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC586243), misc_RNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Strongylocentrotus purpuratus brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC586243), misc_RNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 21)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 21)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 25 aligned letters; 14 identities; 11 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 25:
        identities = 14,
        positives = 19,
        mismatches = 11.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 25)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 11)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332858         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332858441|ref|XM_003316935.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332858441|ref|XM_003316935.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332858441")
            self.assertEqual(alignment.target.annotations["gis"], "332858441")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003316935")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003316935")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003316935.1")
            self.assertEqual(alignment.target.annotations["length"], 8054)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6171)
            self.assertEqual(alignment.target.annotations["end"], 6048)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332858         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332858439|ref|XM_003316934.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332858439|ref|XM_003316934.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332858439")
            self.assertEqual(alignment.target.annotations["gis"], "332858439")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003316934")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003316934")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003316934.1")
            self.assertEqual(alignment.target.annotations["length"], 8593)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6710)
            self.assertEqual(alignment.target.annotations["end"], 6587)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332858         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332858437|ref|XM_514640.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332858437|ref|XM_514640.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332858437")
            self.assertEqual(alignment.target.annotations["gis"], "332858437")
            self.assertEqual(alignment.target.annotations["acc."], "XM_514640")
            self.assertEqual(alignment.target.annotations["accs."], "XM_514640")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_514640.3")
            self.assertEqual(alignment.target.annotations["length"], 8829)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6946)
            self.assertEqual(alignment.target.annotations["end"], 6823)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNTLELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 0.95)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.7)
            self.assertAlmostEqual(alignment.score, 76)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 3 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 3 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 76.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 76.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470302         0 YFLPFQLACETQNVKITVTTLDCLQKL 27
                  0 ..|||.|||...|.|.|.....|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470302053|ref|XM_004347467.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470302053|ref|XM_004347467.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470302053")
            self.assertEqual(alignment.target.annotations["gis"], "470302053")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004347467")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004347467")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004347467.1")
            self.assertEqual(alignment.target.annotations["length"], 6093)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 231)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(alignment.target.seq, "YFLPFQLACETQNVKITVTTLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.3)
            self.assertAlmostEqual(alignment.annotations["bit score"], 37.3)
            self.assertAlmostEqual(alignment.score, 75)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "595528")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Capsaspora owczarzaki ATCC 30864 guanine nucleotide-exchange protein (CAOG_04766) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Capsaspora owczarzaki ATCC 30864 guanine nucleotide-exchange protein (CAOG_04766) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 75.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 75.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|449435         0 VKDGAEHAILKLRTMSCPSDIAENEDILRIFLLACEAKTIKLSVIGLSSLQKLISHDAVT
                  0 ........|..|.............|....|.|||.....|........||.|.......
gi|296147         0 IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIP

gi|449435        60 PSALKEIL 68
                 60 .|.|.||| 68
gi|296147        60 RSRLSEIL 68
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  68],
                              [  0,  68]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|449435759|ref|XM_004135614.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|449435759|ref|XM_004135614.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "449435759")
            self.assertEqual(alignment.target.annotations["gis"], "449435759")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004135614")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004135614")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004135614.1")
            self.assertEqual(alignment.target.annotations["length"], 4903)
            self.assertEqual(alignment.query.annotations["start"], 96)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 72)
            self.assertEqual(alignment.target.annotations["end"], 276)
            self.assertEqual(
                alignment.target.seq,
                "VKDGAEHAILKLRTMSCPSDIAENEDILRIFLLACEAKTIKLSVIGLSSLQKLISHDAVTPSALKEIL",
            )
            self.assertEqual(
                alignment.query.seq,
                "IRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 68))
            self.assertAlmostEqual(alignment.annotations["% identity"], 23.53)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 52)
            self.assertEqual(alignment.annotations["positives"], 37)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 54.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "3659")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cucumis sativus protein MON2 homolog (LOC101218514), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cucumis sativus protein MON2 homolog (LOC101218514), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 58)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 58)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 68 aligned letters; 16 identities; 52 mismatches; 37 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 68:
        identities = 16,
        positives = 37,
        mismatches = 52.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 68)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 52)
            self.assertEqual(counts.positives, 37)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|426391         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNILELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|426391663|ref|XM_004062140.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|426391663|ref|XM_004062140.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "426391663")
            self.assertEqual(alignment.target.annotations["gis"], "426391663")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004062140")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004062140")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004062140.1")
            self.assertEqual(alignment.target.annotations["length"], 8057)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6172)
            self.assertEqual(alignment.target.annotations["end"], 6049)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNILELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9595")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Gorilla gorilla gorilla Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Gorilla gorilla gorilla Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 2 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|426391         0 TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNILELQ 41
                  0 ||...|||||...||......|.|..||....|......|. 41
gi|296147         0 TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK 41
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  41],
                              [  0,  41]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|426391661|ref|XM_004062139.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|426391661|ref|XM_004062139.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "426391661")
            self.assertEqual(alignment.target.annotations["gis"], "426391661")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004062139")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004062139")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004062139.1")
            self.assertEqual(alignment.target.annotations["length"], 8832)
            self.assertEqual(alignment.query.annotations["start"], 225)
            self.assertEqual(alignment.query.annotations["end"], 348)
            self.assertEqual(alignment.target.annotations["start"], 6947)
            self.assertEqual(alignment.target.annotations["end"], 6824)
            self.assertEqual(
                alignment.target.seq, "TLGVSCLQGLHILPSLEDEGVSQITNAFNMIVHVSNILELQ"
            )
            self.assertEqual(
                alignment.query.seq, "TLAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 41))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.59)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 26)
            self.assertEqual(alignment.annotations["positives"], 26)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.41)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9595")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Gorilla gorilla gorilla Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Gorilla gorilla gorilla Ral GTPase activating protein, beta subunit (non-catalytic), transcript variant 1 (RALGAPB), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 35)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 35)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 41 aligned letters; 15 identities; 26 mismatches; 26 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 41:
        identities = 15,
        positives = 26,
        mismatches = 26.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 41)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 26)
            self.assertEqual(counts.positives, 26)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|347973         0 YFLPFELACQSRTPRIVVTALDCLQKL 27
                  0 ..|||.||||||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|347973012|ref|XM_319652.4|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|347973012|ref|XM_319652.4|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "347973012")
            self.assertEqual(alignment.target.annotations["gis"], "347973012")
            self.assertEqual(alignment.target.annotations["acc."], "XM_319652")
            self.assertEqual(alignment.target.annotations["accs."], "XM_319652")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_319652.4")
            self.assertEqual(alignment.target.annotations["length"], 5006)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 246)
            self.assertEqual(alignment.target.annotations["end"], 327)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRTPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 51.85)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "180454")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Anopheles gambiae str. PEST AGAP008906-PA (AgaP_AGAP008906) mRNA, partial cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Anopheles gambiae str. PEST AGAP008906-PA (AgaP_AGAP008906) mRNA, partial cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 27 aligned letters; 14 identities; 13 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 27:
        identities = 14,
        positives = 18,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|339252         0 YFLPFELACSSKSTKIVVIALDCLQKL 27
                  0 ..|||.|||.|...|....|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|339252087|ref|XM_003371219.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|339252087|ref|XM_003371219.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "339252087")
            self.assertEqual(alignment.target.annotations["gis"], "339252087")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003371219")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003371219")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003371219.1")
            self.assertEqual(alignment.target.annotations["length"], 3699)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 222)
            self.assertEqual(alignment.target.annotations["end"], 303)
            self.assertEqual(alignment.target.seq, "YFLPFELACSSKSTKIVVIALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.8)
            self.assertAlmostEqual(alignment.score, 74)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "6334")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Trichinella spiralis putative Sec7 domain protein (Tsp_09497) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Trichinella spiralis putative Sec7 domain protein (Tsp_09497) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 74.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 74.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|189192         0 ISAMSPVPVLARVRLSDVADAYFRINHVVSDL 32
                  0 ....|.||...|.|||...||.....|..... 32
gi|296147         0 LQGLSTVPSIPRSRLSEILDAFIEATHLAMEI 32
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  32],
                              [  0,  32]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|189192213|ref|XM_001932411.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|189192213|ref|XM_001932411.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "189192213")
            self.assertEqual(alignment.target.annotations["gis"], "189192213")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001932411")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001932411")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001932411.1")
            self.assertEqual(alignment.target.annotations["length"], 769)
            self.assertEqual(alignment.query.annotations["start"], 243)
            self.assertEqual(alignment.query.annotations["end"], 339)
            self.assertEqual(alignment.target.annotations["start"], 335)
            self.assertEqual(alignment.target.annotations["end"], 239)
            self.assertEqual(alignment.target.seq, "ISAMSPVPVLARVRLSDVADAYFRINHVVSDL")
            self.assertEqual(alignment.query.seq, "LQGLSTVPSIPRSRLSEILDAFIEATHLAMEI")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 30.9)
            self.assertAlmostEqual(alignment.score, 61)
            self.assertEqual(alignment.shape, (2, 32))
            self.assertAlmostEqual(alignment.annotations["% identity"], 31.25)
            self.assertEqual(alignment.annotations["identical"], 10)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 59.38)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "426418")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pyrenophora tritici-repentis Pt-1C-BFP conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pyrenophora tritici-repentis Pt-1C-BFP conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 43)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 27)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 61.0; 32 aligned letters; 10 identities; 22 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 61.0,
    aligned = 32:
        identities = 10,
        positives = 19,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 32)
            self.assertEqual(counts.identities, 10)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|189192         0 RSLPIIIRAHGLPQLERH 18
                  0 .|..|..|.|....|||| 18
gi|296147         0 KSIEILKRVHSFEELERH 18
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  18],
                              [  0,  18]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|189192213|ref|XM_001932411.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|189192213|ref|XM_001932411.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "189192213")
            self.assertEqual(alignment.target.annotations["gis"], "189192213")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001932411")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001932411")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001932411.1")
            self.assertEqual(alignment.target.annotations["length"], 769)
            self.assertEqual(alignment.query.annotations["start"], 114)
            self.assertEqual(alignment.query.annotations["end"], 168)
            self.assertEqual(alignment.target.annotations["start"], 621)
            self.assertEqual(alignment.target.annotations["end"], 567)
            self.assertEqual(alignment.target.seq, "RSLPIIIRAHGLPQLERH")
            self.assertEqual(alignment.query.seq, "KSIEILKRVHSFEELERH")
            self.assertAlmostEqual(alignment.annotations["evalue"], 1.9)
            self.assertAlmostEqual(alignment.annotations["bit score"], 24.0)
            self.assertAlmostEqual(alignment.score, 46)
            self.assertEqual(alignment.shape, (2, 18))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 8)
            self.assertEqual(alignment.annotations["mismatches"], 10)
            self.assertEqual(alignment.annotations["positives"], 12)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/-2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "426418")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pyrenophora tritici-repentis Pt-1C-BFP conserved hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pyrenophora tritici-repentis Pt-1C-BFP conserved hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 43)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 15)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 46.0; 18 aligned letters; 8 identities; 10 mismatches; 12 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 46.0,
    aligned = 18:
        identities = 8,
        positives = 12,
        mismatches = 10.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 18)
            self.assertEqual(counts.identities, 8)
            self.assertEqual(counts.mismatches, 10)
            self.assertEqual(counts.positives, 12)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|426242         0 YFLPFELACQSRSPRVVSTSLDCLQKL 27
                  0 ..|||.||||||..........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|426242124|ref|XM_004014876.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|426242124|ref|XM_004014876.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "426242124")
            self.assertEqual(alignment.target.annotations["gis"], "426242124")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004014876")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004014876")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004014876.1")
            self.assertEqual(alignment.target.annotations["length"], 5780)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 240)
            self.assertEqual(alignment.target.annotations["end"], 321)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2.5)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.3)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9940")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Ovis aries ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Ovis aries ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 73.0; 27 aligned letters; 13 identities; 14 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 73.0,
    aligned = 27:
        identities = 13,
        positives = 20,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|329663         0 YFLPFELACQSRSPRVVSTSLDCLQKL 27
                  0 ..|||.||||||..........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|329663901|ref|NM_001205652.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|329663901|ref|NM_001205652.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "329663901")
            self.assertEqual(alignment.target.annotations["gis"], "329663901")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001205652")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001205652")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001205652.1")
            self.assertEqual(alignment.target.annotations["length"], 8869)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 2.5)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.3)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9913")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Bos taurus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Bos taurus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 73.0; 27 aligned letters; 13 identities; 14 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 73.0,
    aligned = 27:
        identities = 13,
        positives = 20,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|167533         0 PFRLACECKSAKVTRTALDCLQKMMAYGHINSHMMAEV 38
                  0 ||.|||....||.|..|..|||.......|......|. 38
gi|296147         0 PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEI 38
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  38],
                              [  0,  38]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|167533856|ref|XM_001748555.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|167533856|ref|XM_001748555.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "167533856")
            self.assertEqual(alignment.target.annotations["gis"], "167533856")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001748555")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001748555")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001748555.1")
            self.assertEqual(alignment.target.annotations["length"], 5818)
            self.assertEqual(alignment.query.annotations["start"], 183)
            self.assertEqual(alignment.query.annotations["end"], 297)
            self.assertEqual(alignment.target.annotations["start"], 619)
            self.assertEqual(alignment.target.annotations["end"], 733)
            self.assertEqual(
                alignment.target.seq, "PFRLACECKSAKVTRTALDCLQKMMAYGHINSHMMAEV"
            )
            self.assertEqual(
                alignment.query.seq, "PFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEI"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 2.5)
            self.assertAlmostEqual(alignment.annotations["bit score"], 36.3)
            self.assertAlmostEqual(alignment.score, 73)
            self.assertEqual(alignment.shape, (2, 38))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.84)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.53)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "431895")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Monosiga brevicollis MX1 predicted protein MONBRDRAFT_33770 mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Monosiga brevicollis MX1 predicted protein MONBRDRAFT_33770 mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 33)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 73.0; 38 aligned letters; 14 identities; 24 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 73.0,
    aligned = 38:
        identities = 14,
        positives = 23,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 38)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410970         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410970929|ref|XM_003991879.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410970929|ref|XM_003991879.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410970929")
            self.assertEqual(alignment.target.annotations["gis"], "410970929")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003991879")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003991879")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003991879.1")
            self.assertEqual(alignment.target.annotations["length"], 3983)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 3234)
            self.assertEqual(alignment.target.annotations["end"], 3294)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/1")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9685")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Felis catus EPH receptor B3 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Felis catus EPH receptor B3 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410929         0 YVLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410929672|ref|XM_003978175.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410929672|ref|XM_003978175.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410929672")
            self.assertEqual(alignment.target.annotations["gis"], "410929672")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003978175")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003978175")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003978175.1")
            self.assertEqual(alignment.target.annotations["length"], 4929)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 231)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(alignment.target.seq, "YVLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "31033")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Takifugu rubripes brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC101076459), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Takifugu rubripes brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC101076459), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|402903         0 DSISSFEKTGARSQWRGTQDSSGDPCRGRSFQLP*LAT 38
                  0 ..|..|.....|..|.|.|......|.||.|..||||. 38
gi|296147         0 EGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LAS 38
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  38],
                              [  0,  38]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|402903089|ref|XM_003914364.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|402903089|ref|XM_003914364.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "402903089")
            self.assertEqual(alignment.target.annotations["gis"], "402903089")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003914364")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003914364")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003914364.1")
            self.assertEqual(alignment.target.annotations["length"], 3776)
            self.assertEqual(alignment.query.annotations["start"], 309)
            self.assertEqual(alignment.query.annotations["end"], 195)
            self.assertEqual(alignment.target.annotations["start"], 2581)
            self.assertEqual(alignment.target.annotations["end"], 2467)
            self.assertEqual(
                alignment.target.seq, "DSISSFEKTGARSQWRGTQDSSGDPCRGRSFQLP*LAT"
            )
            self.assertEqual(
                alignment.query.seq, "EGIQNFRQPASRNRWNG*QSL*ALHCQGRHFSIP*LAS"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 38))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.84)
            self.assertEqual(alignment.annotations["identical"], 14)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 60.53)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-3/-2")
            self.assertEqual(alignment.query.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9555")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Papio anubis CBP80/20-dependent translation initiation factor-like (LOC101009629), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Papio anubis CBP80/20-dependent translation initiation factor-like (LOC101009629), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 33)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 38 aligned letters; 14 identities; 24 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 38:
        identities = 14,
        positives = 23,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 38)
            self.assertEqual(counts.identities, 14)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|383853         0 YFLPFELACQSKSPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|383853967|ref|XM_003702446.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|383853967|ref|XM_003702446.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "383853967")
            self.assertEqual(alignment.target.annotations["gis"], "383853967")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003702446")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003702446")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003702446.1")
            self.assertEqual(alignment.target.annotations["length"], 5094)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 216)
            self.assertEqual(alignment.target.annotations["end"], 297)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "143995")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Megachile rotundata ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Megachile rotundata ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|380017         0 YFLPFELACQSKSPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|380017270|ref|XM_003692535.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|380017270|ref|XM_003692535.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "380017270")
            self.assertEqual(alignment.target.annotations["gis"], "380017270")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003692535")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003692535")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003692535.1")
            self.assertEqual(alignment.target.annotations["length"], 5723)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 521)
            self.assertEqual(alignment.target.annotations["end"], 602)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "7463")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Apis florea ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Apis florea ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|350411         0 YFLPFELACQSKSPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|350411438|ref|XM_003489304.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350411438|ref|XM_003489304.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "350411438")
            self.assertEqual(alignment.target.annotations["gis"], "350411438")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003489304")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003489304")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003489304.1")
            self.assertEqual(alignment.target.annotations["length"], 5094)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 216)
            self.assertEqual(alignment.target.annotations["end"], 297)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "132113")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Bombus impatiens brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100743555), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Bombus impatiens brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100743555), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|348539         0 YVLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|348539090|ref|XM_003456975.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|348539090|ref|XM_003456975.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "348539090")
            self.assertEqual(alignment.target.annotations["gis"], "348539090")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003456975")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003456975")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003456975.1")
            self.assertEqual(alignment.target.annotations["length"], 5589)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 306)
            self.assertEqual(alignment.target.annotations["end"], 387)
            self.assertEqual(alignment.target.seq, "YVLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "8128")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Oreochromis niloticus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Oreochromis niloticus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|345796         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|345796385|ref|XM_003434116.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|345796385|ref|XM_003434116.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "345796385")
            self.assertEqual(alignment.target.annotations["gis"], "345796385")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003434116")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003434116")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003434116.1")
            self.assertEqual(alignment.target.annotations["length"], 3664)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2945)
            self.assertEqual(alignment.target.annotations["end"], 3005)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9615")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Canis lupus familiaris EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Canis lupus familiaris EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|345796         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|345796383|ref|XM_545232.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|345796383|ref|XM_545232.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "345796383")
            self.assertEqual(alignment.target.annotations["gis"], "345796383")
            self.assertEqual(alignment.target.annotations["acc."], "XM_545232")
            self.assertEqual(alignment.target.annotations["accs."], "XM_545232")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_545232.3")
            self.assertEqual(alignment.target.annotations["length"], 3660)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2941)
            self.assertEqual(alignment.target.annotations["end"], 3001)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9615")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Canis lupus familiaris EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Canis lupus familiaris EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|340729         0 YFLPFELACQSKSPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|340729748|ref|XM_003403110.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|340729748|ref|XM_003403110.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "340729748")
            self.assertEqual(alignment.target.annotations["gis"], "340729748")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003403110")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003403110")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003403110.1")
            self.assertEqual(alignment.target.annotations["length"], 7331)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 621)
            self.assertEqual(alignment.target.annotations["end"], 702)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "30195")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Bombus terrestris brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100648040), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Bombus terrestris brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100648040), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|338716         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|338716130|ref|XM_001497451.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|338716130|ref|XM_001497451.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "338716130")
            self.assertEqual(alignment.target.annotations["gis"], "338716130")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001497451")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001497451")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001497451.3")
            self.assertEqual(alignment.target.annotations["length"], 3659)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2940)
            self.assertEqual(alignment.target.annotations["end"], 3000)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/1")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9796")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Equus caballus EPH receptor B3 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Equus caballus EPH receptor B3 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|328778         0 YFLPFELACQSKSPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|328778548|ref|XM_003249467.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|328778548|ref|XM_003249467.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "328778548")
            self.assertEqual(alignment.target.annotations["gis"], "328778548")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003249467")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003249467")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003249467.1")
            self.assertEqual(alignment.target.annotations["length"], 5773)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 519)
            self.assertEqual(alignment.target.annotations["end"], 600)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7460")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Apis mellifera sec71 protein (sec71), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Apis mellifera sec71 protein (sec71), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|301759         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|301759744|ref|XM_002915676.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|301759744|ref|XM_002915676.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "301759744")
            self.assertEqual(alignment.target.annotations["gis"], "301759744")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002915676")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002915676")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002915676.1")
            self.assertEqual(alignment.target.annotations["length"], 3673)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2954)
            self.assertEqual(alignment.target.annotations["end"], 3014)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9646")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Ailuropoda melanoleuca EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Ailuropoda melanoleuca EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|301759         0 AGLLDFWMPGLRLWPRRWKF 20
                  0 ||.|.||||.|||...||.| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|301759742|ref|XM_002915675.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|301759742|ref|XM_002915675.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "301759742")
            self.assertEqual(alignment.target.annotations["gis"], "301759742")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002915675")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002915675")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002915675.1")
            self.assertEqual(alignment.target.annotations["length"], 3658)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2939)
            self.assertEqual(alignment.target.annotations["end"], 2999)
            self.assertEqual(alignment.target.seq, "AGLLDFWMPGLRLWPRRWKF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9646")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Ailuropoda melanoleuca EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Ailuropoda melanoleuca EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|292626         0 YVLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|292626951|ref|XM_002666467.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|292626951|ref|XM_002666467.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "292626951")
            self.assertEqual(alignment.target.annotations["gis"], "292626951")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002666467")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002666467")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002666467.1")
            self.assertEqual(alignment.target.annotations["length"], 5942)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 405)
            self.assertEqual(alignment.target.annotations["end"], 486)
            self.assertEqual(alignment.target.seq, "YVLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7955")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Danio rerio ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Danio rerio ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (arfgef2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|237836         0 PWCRDAQRECRPFSFFVR*RCKRFFSPGL 29
                  0 ||...|.|.|.||..|....|..|..|.| 29
gi|296147         0 PWQCNAYRDCQPFHLFLEAGCLKFWMPSL 29
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  29],
                              [  0,  29]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|237836078|ref|XM_002367296.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|237836078|ref|XM_002367296.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "237836078")
            self.assertEqual(alignment.target.annotations["gis"], "237836078")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002367296")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002367296")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002367296.1")
            self.assertEqual(alignment.target.annotations["length"], 6159)
            self.assertEqual(alignment.query.annotations["start"], 226)
            self.assertEqual(alignment.query.annotations["end"], 313)
            self.assertEqual(alignment.target.annotations["start"], 1016)
            self.assertEqual(alignment.target.annotations["end"], 1103)
            self.assertEqual(alignment.target.seq, "PWCRDAQRECRPFSFFVR*RCKRFFSPGL")
            self.assertEqual(alignment.query.seq, "PWQCNAYRDCQPFHLFLEAGCLKFWMPSL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 3.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.9)
            self.assertAlmostEqual(alignment.score, 72)
            self.assertEqual(alignment.shape, (2, 29))
            self.assertAlmostEqual(alignment.annotations["% identity"], 41.38)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 17)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "508771")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Toxoplasma gondii ME49 hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Toxoplasma gondii ME49 hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 25)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 25)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 72.0; 29 aligned letters; 12 identities; 17 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 72.0,
    aligned = 29:
        identities = 12,
        positives = 18,
        mismatches = 17.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 29)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 17)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|396462         0 SRKDLSRRPHFISPFLIACGTRNAKV 26
                  0 |...|.|.|.|..||..||..||||. 26
gi|296147         0 SFEELERHPDFALPFVLACQSRNAKM 26
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  26],
                              [  0,  26]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|396462349|ref|XM_003835738.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|396462349|ref|XM_003835738.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "396462349")
            self.assertEqual(alignment.target.annotations["gis"], "396462349")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003835738")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003835738")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003835738.1")
            self.assertEqual(alignment.target.annotations["length"], 6858)
            self.assertEqual(alignment.query.annotations["start"], 144)
            self.assertEqual(alignment.query.annotations["end"], 222)
            self.assertEqual(alignment.target.annotations["start"], 402)
            self.assertEqual(alignment.target.annotations["end"], 480)
            self.assertEqual(alignment.target.seq, "SRKDLSRRPHFISPFLIACGTRNAKV")
            self.assertEqual(alignment.query.seq, "SFEELERHPDFALPFVLACQSRNAKM")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 26))
            self.assertAlmostEqual(alignment.annotations["% identity"], 50.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 73.08)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "985895")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Leptosphaeria maculans JN3 hypothetical protein (LEMA_P051270.1) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Leptosphaeria maculans JN3 hypothetical protein (LEMA_P051270.1) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 22)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 22)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 26 aligned letters; 13 identities; 13 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 26:
        identities = 13,
        positives = 19,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 26)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|268570         0 YFLPFELACNSKNPRVVITALDCLQKL 27
                  0 ..|||.|||.|.|......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|268570183|ref|XM_002640666.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|268570183|ref|XM_002640666.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "268570183")
            self.assertEqual(alignment.target.annotations["gis"], "268570183")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002640666")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002640666")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002640666.1")
            self.assertEqual(alignment.target.annotations["length"], 4782)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 249)
            self.assertEqual(alignment.target.annotations["end"], 330)
            self.assertEqual(alignment.target.seq, "YFLPFELACNSKNPRVVITALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "6238")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Caenorhabditis briggsae C. briggsae CBR-AGEF-1 protein (Cbr-agef-1) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Caenorhabditis briggsae C. briggsae CBR-AGEF-1 protein (Cbr-agef-1) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 18,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|198473         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|198473316|ref|XM_001356210.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|198473316|ref|XM_001356210.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "198473316")
            self.assertEqual(alignment.target.annotations["gis"], "198473316")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001356210")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001356210")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001356210.2")
            self.assertEqual(alignment.target.annotations["length"], 4935)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "46245")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila pseudoobscura pseudoobscura GA20452 (Dpse\GA20452), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila pseudoobscura pseudoobscura GA20452 (Dpse\GA20452), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|196008         0 DYFLPFELACKSRCSRIVIASLDCLQKL 28
                  0 |..|||.|||.||..........|||.| 28
gi|296147         0 DFALPFVLACQSRNAKMTTLAMQCLQGL 28
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  28],
                              [  0,  28]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|196008366|ref|XM_002114013.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|196008366|ref|XM_002114013.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "196008366")
            self.assertEqual(alignment.target.annotations["gis"], "196008366")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002114013")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002114013")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002114013.1")
            self.assertEqual(alignment.target.annotations["length"], 5498)
            self.assertEqual(alignment.query.annotations["start"], 171)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 225)
            self.assertEqual(alignment.target.annotations["end"], 309)
            self.assertEqual(alignment.target.seq, "DYFLPFELACKSRCSRIVIASLDCLQKL")
            self.assertEqual(alignment.query.seq, "DFALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 28))
            self.assertAlmostEqual(alignment.annotations["% identity"], 46.43)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 71.43)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "10228")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Trichoplax adhaerens hypothetical protein, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Trichoplax adhaerens hypothetical protein, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 24)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 24)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 28 aligned letters; 13 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 28:
        identities = 13,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 28)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195579         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195579057|ref|XM_002079343.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195579057|ref|XM_002079343.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195579057")
            self.assertEqual(alignment.target.annotations["gis"], "195579057")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002079343")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002079343")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002079343.1")
            self.assertEqual(alignment.target.annotations["length"], 4869)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 219)
            self.assertEqual(alignment.target.annotations["end"], 300)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7240")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila simulans GD23923 (Dsim\GD23923), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila simulans GD23923 (Dsim\GD23923), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195472         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195472698|ref|XM_002088601.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195472698|ref|XM_002088601.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195472698")
            self.assertEqual(alignment.target.annotations["gis"], "195472698")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002088601")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002088601")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002088601.1")
            self.assertEqual(alignment.target.annotations["length"], 4962)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7245")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila yakuba GE18681 (Dyak\GE18681), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila yakuba GE18681 (Dyak\GE18681), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195438         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195438259|ref|XM_002067019.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195438259|ref|XM_002067019.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195438259")
            self.assertEqual(alignment.target.annotations["gis"], "195438259")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002067019")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002067019")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002067019.1")
            self.assertEqual(alignment.target.annotations["length"], 5019)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7260")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila willistoni GK24228 (Dwil\GK24228), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila willistoni GK24228 (Dwil\GK24228), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195397         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195397689|ref|XM_002057425.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195397689|ref|XM_002057425.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195397689")
            self.assertEqual(alignment.target.annotations["gis"], "195397689")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002057425")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002057425")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002057425.1")
            self.assertEqual(alignment.target.annotations["length"], 5145)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7244")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila virilis GJ18143 (Dvir\GJ18143), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila virilis GJ18143 (Dvir\GJ18143), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195338         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195338276|ref|XM_002035715.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195338276|ref|XM_002035715.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195338276")
            self.assertEqual(alignment.target.annotations["gis"], "195338276")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002035715")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002035715")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002035715.1")
            self.assertEqual(alignment.target.annotations["length"], 4962)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7238")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila sechellia GM15214 (Dsec\GM15214), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila sechellia GM15214 (Dsec\GM15214), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195164         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195164721|ref|XM_002023159.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195164721|ref|XM_002023159.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195164721")
            self.assertEqual(alignment.target.annotations["gis"], "195164721")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002023159")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002023159")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002023159.1")
            self.assertEqual(alignment.target.annotations["length"], 4935)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7234")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila persimilis GL21229 (Dper\GL21229), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila persimilis GL21229 (Dper\GL21229), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195119         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195119048|ref|XM_002004008.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195119048|ref|XM_002004008.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195119048")
            self.assertEqual(alignment.target.annotations["gis"], "195119048")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002004008")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002004008")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002004008.1")
            self.assertEqual(alignment.target.annotations["length"], 5133)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7230")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila mojavensis GI18236 (Dmoj\GI18236), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila mojavensis GI18236 (Dmoj\GI18236), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|195031         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|195031427|ref|XM_001988304.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|195031427|ref|XM_001988304.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "195031427")
            self.assertEqual(alignment.target.annotations["gis"], "195031427")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001988304")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001988304")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001988304.1")
            self.assertEqual(alignment.target.annotations["length"], 5130)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7222")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila grimshawi GH11113 (Dgri\GH11113), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila grimshawi GH11113 (Dgri\GH11113), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|194860         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|194860432|ref|XM_001969546.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|194860432|ref|XM_001969546.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "194860432")
            self.assertEqual(alignment.target.annotations["gis"], "194860432")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001969546")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001969546")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001969546.1")
            self.assertEqual(alignment.target.annotations["length"], 4962)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 243)
            self.assertEqual(alignment.target.annotations["end"], 324)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7220")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila erecta GG23880 (Dere\GG23880), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila erecta GG23880 (Dere\GG23880), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|194761         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|194761139|ref|XM_001962754.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|194761139|ref|XM_001962754.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "194761139")
            self.assertEqual(alignment.target.annotations["gis"], "194761139")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001962754")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001962754")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001962754.1")
            self.assertEqual(alignment.target.annotations["length"], 4971)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 246)
            self.assertEqual(alignment.target.annotations["end"], 327)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7217")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                r"Drosophila ananassae GF14256 (Dana\GF14256), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                r"Drosophila ananassae GF14256 (Dana\GF14256), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|170037         0 YFLPFELACQSKTPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|170037186|ref|XM_001846389.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|170037186|ref|XM_001846389.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "170037186")
            self.assertEqual(alignment.target.annotations["gis"], "170037186")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001846389")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001846389")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001846389.1")
            self.assertEqual(alignment.target.annotations["length"], 6192)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 1356)
            self.assertEqual(alignment.target.annotations["end"], 1437)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKTPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7176")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Culex quinquefasciatus brefeldin A-inhibited guanine nucleotide-exchange protein 1, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Culex quinquefasciatus brefeldin A-inhibited guanine nucleotide-exchange protein 1, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 18,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|157134         0 YFLPFELACQSKTPRIVVTALDCLQKL 27
                  0 ..|||.|||||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|157134230|ref|XM_001663149.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|157134230|ref|XM_001663149.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "157134230")
            self.assertEqual(alignment.target.annotations["gis"], "157134230")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001663149")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001663149")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001663149.1")
            self.assertEqual(alignment.target.annotations["length"], 5320)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 132)
            self.assertEqual(alignment.target.annotations["end"], 213)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKTPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7159")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aedes aegypti brefeldin a-inhibited guanine nucleotide-exchange protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aedes aegypti brefeldin a-inhibited guanine nucleotide-exchange protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 18,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156386         0 YLLPFELACQSKCPRIVTTSLDCLQKL 27
                  0 ..|||.|||||......|....|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156386529|ref|XM_001633915.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156386529|ref|XM_001633915.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156386529")
            self.assertEqual(alignment.target.annotations["gis"], "156386529")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001633915")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001633915")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001633915.1")
            self.assertEqual(alignment.target.annotations["length"], 5502)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 213)
            self.assertEqual(alignment.target.annotations["end"], 294)
            self.assertEqual(alignment.target.seq, "YLLPFELACQSKCPRIVTTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "45351")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g102625) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g102625) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|245841         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|24584188|ref|NM_165059.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|24584188|ref|NM_165059.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "24584188")
            self.assertEqual(alignment.target.annotations["gis"], "24584188")
            self.assertEqual(alignment.target.annotations["acc."], "NM_165059")
            self.assertEqual(alignment.target.annotations["accs."], "NM_165059")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_165059.1")
            self.assertEqual(alignment.target.annotations["length"], 5672)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 541)
            self.assertEqual(alignment.target.annotations["end"], 622)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "7227")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Drosophila melanogaster sec71 (sec71), transcript variant B, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Drosophila melanogaster sec71 (sec71), transcript variant B, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|245841         0 YFLPFELACKSRSPRIVVTALDCLQKL 27
                  0 ..|||.|||.||.......|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|24584186|ref|NM_135831.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|24584186|ref|NM_135831.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "24584186")
            self.assertEqual(alignment.target.annotations["gis"], "24584186")
            self.assertEqual(alignment.target.annotations["acc."], "NM_135831")
            self.assertEqual(alignment.target.annotations["accs."], "NM_135831")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_135831.2")
            self.assertEqual(alignment.target.annotations["length"], 5799)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 544)
            self.assertEqual(alignment.target.annotations["end"], 625)
            self.assertEqual(alignment.target.seq, "YFLPFELACKSRSPRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 4.6)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.4)
            self.assertAlmostEqual(alignment.score, 71)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "7227")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Drosophila melanogaster sec71 (sec71), transcript variant A, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Drosophila melanogaster sec71 (sec71), transcript variant A, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 71.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 71.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|157110         0 FLIVGSNCWLFIVSSDWLNFFFS 23
                  0 ........|.......||||||| 23
gi|296147         0 YVLFSISQWIYH*HGEWLNFFFS 23
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  23],
                              [  0,  23]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|157110325|ref|XM_001651005.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|157110325|ref|XM_001651005.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "157110325")
            self.assertEqual(alignment.target.annotations["gis"], "157110325")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001651005")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001651005")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001651005.1")
            self.assertEqual(alignment.target.annotations["length"], 9654)
            self.assertEqual(alignment.query.annotations["start"], 145)
            self.assertEqual(alignment.query.annotations["end"], 76)
            self.assertEqual(alignment.target.annotations["start"], 5691)
            self.assertEqual(alignment.target.annotations["end"], 5622)
            self.assertEqual(alignment.target.seq, "FLIVGSNCWLFIVSSDWLNFFFS")
            self.assertEqual(alignment.query.seq, "YVLFSISQWIYH*HGEWLNFFFS")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.2)
            self.assertAlmostEqual(alignment.annotations["bit score"], 27.6)
            self.assertAlmostEqual(alignment.score, 54)
            self.assertEqual(alignment.shape, (2, 23))
            self.assertAlmostEqual(alignment.annotations["% identity"], 34.78)
            self.assertEqual(alignment.annotations["identical"], 8)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 15)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.22)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7159")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aedes aegypti hypothetical protein AaeL_AAEL005529 partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aedes aegypti hypothetical protein AaeL_AAEL005529 partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 40)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 20)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 54.0; 23 aligned letters; 8 identities; 15 mismatches; 15 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 54.0,
    aligned = 23:
        identities = 8,
        positives = 15,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 23)
            self.assertEqual(counts.identities, 8)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 15)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|157110         0 GNWFHFFFSWFLIVGSNWLNFFLSWFFIISRNW 33
                  0 |.|..||||...|.....|.....|.......| 33
gi|296147         0 GEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSW 33
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  33],
                              [  0,  33]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|157110325|ref|XM_001651005.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|157110325|ref|XM_001651005.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "157110325")
            self.assertEqual(alignment.target.annotations["gis"], "157110325")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001651005")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001651005")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001651005.1")
            self.assertEqual(alignment.target.annotations["length"], 9654)
            self.assertEqual(alignment.query.annotations["start"], 103)
            self.assertEqual(alignment.query.annotations["end"], 4)
            self.assertEqual(alignment.target.annotations["start"], 5517)
            self.assertEqual(alignment.target.annotations["end"], 5418)
            self.assertEqual(alignment.target.seq, "GNWFHFFFSWFLIVGSNWLNFFLSWFFIISRNW")
            self.assertEqual(alignment.query.seq, "GEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSW")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.2)
            self.assertAlmostEqual(alignment.annotations["bit score"], 24.9)
            self.assertAlmostEqual(alignment.score, 48)
            self.assertEqual(alignment.shape, (2, 33))
            self.assertAlmostEqual(alignment.annotations["% identity"], 30.30)
            self.assertEqual(alignment.annotations["identical"], 10)
            self.assertEqual(alignment.annotations["mismatches"], 23)
            self.assertEqual(alignment.annotations["positives"], 15)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 45.45)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/-1")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7159")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aedes aegypti hypothetical protein AaeL_AAEL005529 partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aedes aegypti hypothetical protein AaeL_AAEL005529 partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 40)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 28)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 48.0; 33 aligned letters; 10 identities; 23 mismatches; 15 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 48.0,
    aligned = 33:
        identities = 10,
        positives = 15,
        mismatches = 23.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 33)
            self.assertEqual(counts.identities, 10)
            self.assertEqual(counts.mismatches, 23)
            self.assertEqual(counts.positives, 15)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156388         0 CQPFLRFLEWGNMDL*LPALLVL 23
                  0 ||||..|||.|......|.|..| 23
gi|296147         0 CQPFHLFLEAGCLKFWMPSLRLL 23
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  23],
                              [  0,  23]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156388828|ref|XM_001634645.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156388828|ref|XM_001634645.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156388828")
            self.assertEqual(alignment.target.annotations["gis"], "156388828")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001634645")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001634645")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001634645.1")
            self.assertEqual(alignment.target.annotations["length"], 528)
            self.assertEqual(alignment.query.annotations["start"], 253)
            self.assertEqual(alignment.query.annotations["end"], 322)
            self.assertEqual(alignment.target.annotations["start"], 352)
            self.assertEqual(alignment.target.annotations["end"], 421)
            self.assertEqual(alignment.target.seq, "CQPFLRFLEWGNMDL*LPALLVL")
            self.assertEqual(alignment.query.seq, "CQPFHLFLEAGCLKFWMPSLRLL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 26.3)
            self.assertAlmostEqual(alignment.score, 51)
            self.assertEqual(alignment.shape, (2, 23))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.83)
            self.assertEqual(alignment.annotations["identical"], 11)
            self.assertEqual(alignment.annotations["mismatches"], 12)
            self.assertEqual(alignment.annotations["positives"], 15)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.22)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "45351")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g26815) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g26815) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 20)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 51.0; 23 aligned letters; 11 identities; 12 mismatches; 15 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 51.0,
    aligned = 23:
        identities = 11,
        positives = 15,
        mismatches = 12.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 23)
            self.assertEqual(counts.identities, 11)
            self.assertEqual(counts.mismatches, 12)
            self.assertEqual(counts.positives, 15)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156388         0 RNAKVMVIFLWCLSLLSAIPPV 22
                  0 ||||.......||..||..|.. 22
gi|296147         0 RNAKMTTLAMQCLQGLSTVPSI 22
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  22],
                              [  0,  22]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156388828|ref|XM_001634645.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156388828|ref|XM_001634645.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156388828")
            self.assertEqual(alignment.target.annotations["gis"], "156388828")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001634645")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001634645")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001634645.1")
            self.assertEqual(alignment.target.annotations["length"], 528)
            self.assertEqual(alignment.query.annotations["start"], 207)
            self.assertEqual(alignment.query.annotations["end"], 273)
            self.assertEqual(alignment.target.annotations["start"], 306)
            self.assertEqual(alignment.target.annotations["end"], 372)
            self.assertEqual(alignment.target.seq, "RNAKVMVIFLWCLSLLSAIPPV")
            self.assertEqual(alignment.query.seq, "RNAKMTTLAMQCLQGLSTVPSI")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 25.4)
            self.assertAlmostEqual(alignment.score, 49)
            self.assertEqual(alignment.shape, (2, 22))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.91)
            self.assertEqual(alignment.annotations["identical"], 9)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.64)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "45351")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g26815) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g26815) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 19)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 49.0; 22 aligned letters; 9 identities; 13 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 49.0,
    aligned = 22:
        identities = 9,
        positives = 14,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 22)
            self.assertEqual(counts.identities, 9)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156359         0 CQPFLRFLEWGNMDL*LPALLVL 23
                  0 ||||..|||.|......|.|..| 23
gi|296147         0 CQPFHLFLEAGCLKFWMPSLRLL 23
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  23],
                              [  0,  23]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156359702|ref|XM_001624855.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156359702|ref|XM_001624855.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156359702")
            self.assertEqual(alignment.target.annotations["gis"], "156359702")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001624855")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001624855")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001624855.1")
            self.assertEqual(alignment.target.annotations["length"], 528)
            self.assertEqual(alignment.query.annotations["start"], 253)
            self.assertEqual(alignment.query.annotations["end"], 322)
            self.assertEqual(alignment.target.annotations["start"], 352)
            self.assertEqual(alignment.target.annotations["end"], 421)
            self.assertEqual(alignment.target.seq, "CQPFLRFLEWGNMDL*LPALLVL")
            self.assertEqual(alignment.query.seq, "CQPFHLFLEAGCLKFWMPSLRLL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 26.3)
            self.assertAlmostEqual(alignment.score, 51)
            self.assertEqual(alignment.shape, (2, 23))
            self.assertAlmostEqual(alignment.annotations["% identity"], 47.83)
            self.assertEqual(alignment.annotations["identical"], 11)
            self.assertEqual(alignment.annotations["mismatches"], 12)
            self.assertEqual(alignment.annotations["positives"], 15)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 65.22)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "45351")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g16273) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g16273) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 20)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 51.0; 23 aligned letters; 11 identities; 12 mismatches; 15 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 51.0,
    aligned = 23:
        identities = 11,
        positives = 15,
        mismatches = 12.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 23)
            self.assertEqual(counts.identities, 11)
            self.assertEqual(counts.mismatches, 12)
            self.assertEqual(counts.positives, 15)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|156359         0 RNAKVMVIFLWCLSLLSAIPPV 22
                  0 ||||.......||..||..|.. 22
gi|296147         0 RNAKMTTLAMQCLQGLSTVPSI 22
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  22],
                              [  0,  22]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|156359702|ref|XM_001624855.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|156359702|ref|XM_001624855.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "156359702")
            self.assertEqual(alignment.target.annotations["gis"], "156359702")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001624855")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001624855")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001624855.1")
            self.assertEqual(alignment.target.annotations["length"], 528)
            self.assertEqual(alignment.query.annotations["start"], 207)
            self.assertEqual(alignment.query.annotations["end"], 273)
            self.assertEqual(alignment.target.annotations["start"], 306)
            self.assertEqual(alignment.target.annotations["end"], 372)
            self.assertEqual(alignment.target.seq, "RNAKVMVIFLWCLSLLSAIPPV")
            self.assertEqual(alignment.query.seq, "RNAKMTTLAMQCLQGLSTVPSI")
            self.assertAlmostEqual(alignment.annotations["evalue"], 5.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 25.4)
            self.assertAlmostEqual(alignment.score, 49)
            self.assertEqual(alignment.shape, (2, 22))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.91)
            self.assertEqual(alignment.annotations["identical"], 9)
            self.assertEqual(alignment.annotations["mismatches"], 13)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 63.64)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "45351")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g16273) partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Nematostella vectensis predicted protein (NEMVEDRAFT_v1g16273) partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 19)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 49.0; 22 aligned letters; 9 identities; 13 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 49.0,
    aligned = 22:
        identities = 9,
        positives = 14,
        mismatches = 13.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 22)
            self.assertEqual(counts.identities, 9)
            self.assertEqual(counts.mismatches, 13)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|471359         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|471359494|ref|XM_004370266.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|471359494|ref|XM_004370266.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "471359494")
            self.assertEqual(alignment.target.annotations["gis"], "471359494")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004370266")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004370266")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004370266.1")
            self.assertEqual(alignment.target.annotations["length"], 9039)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 352)
            self.assertEqual(alignment.target.annotations["end"], 433)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "127582")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Trichechus manatus latirostris ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Trichechus manatus latirostris ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470652         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470652205|ref|XM_004329148.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470652205|ref|XM_004329148.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470652205")
            self.assertEqual(alignment.target.annotations["gis"], "470652205")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004329148")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004329148")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004329148.1")
            self.assertEqual(alignment.target.annotations["length"], 3458)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 75)
            self.assertEqual(alignment.target.annotations["end"], 156)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9739")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Tursiops truncatus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Tursiops truncatus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470125         0 FVQSCSSPNFKFSTSSSEHSQGSSNSKSIPRLRVSD 36
                  0 ||..|.|.|.|..|......||.|...||||.|.|. 36
gi|296147         0 FVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE 36
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  36],
                              [  0,  36]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470125017|ref|XM_004298456.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470125017|ref|XM_004298456.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470125017")
            self.assertEqual(alignment.target.annotations["gis"], "470125017")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004298456")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004298456")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004298456.1")
            self.assertEqual(alignment.target.annotations["length"], 3617)
            self.assertEqual(alignment.query.annotations["start"], 186)
            self.assertEqual(alignment.query.annotations["end"], 294)
            self.assertEqual(alignment.target.annotations["start"], 1362)
            self.assertEqual(alignment.target.annotations["end"], 1470)
            self.assertEqual(
                alignment.target.seq, "FVQSCSSPNFKFSTSSSEHSQGSSNSKSIPRLRVSD"
            )
            self.assertEqual(
                alignment.query.seq, "FVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSE"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 36))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 20)
            self.assertEqual(alignment.annotations["positives"], 22)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 61.11)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "101020")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Fragaria vesca subsp. vesca cleavage and polyadenylation specificity factor subunit 3-II-like (LOC101304092), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Fragaria vesca subsp. vesca cleavage and polyadenylation specificity factor subunit 3-II-like (LOC101304092), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 31)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 31)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 36 aligned letters; 16 identities; 20 mismatches; 22 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 36:
        identities = 16,
        positives = 22,
        mismatches = 20.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 36)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 20)
            self.assertEqual(counts.positives, 22)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|466073         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|466073472|ref|XM_004282882.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|466073472|ref|XM_004282882.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "466073472")
            self.assertEqual(alignment.target.annotations["gis"], "466073472")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004282882")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004282882")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004282882.1")
            self.assertEqual(alignment.target.annotations["length"], 9027)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 347)
            self.assertEqual(alignment.target.annotations["end"], 428)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9733")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Orcinus orca ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Orcinus orca ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|449492         0 RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL 37
                  0 |.||..|...|....|....|.|.|.|||..|.|..| 37
gi|296147         0 RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|449492807|ref|XM_004159059.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|449492807|ref|XM_004159059.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "449492807")
            self.assertEqual(alignment.target.annotations["gis"], "449492807")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004159059")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004159059")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004159059.1")
            self.assertEqual(alignment.target.annotations["length"], 1991)
            self.assertEqual(alignment.query.annotations["start"], 76)
            self.assertEqual(alignment.query.annotations["end"], 187)
            self.assertEqual(alignment.target.annotations["start"], 533)
            self.assertEqual(alignment.target.annotations["end"], 644)
            self.assertEqual(
                alignment.target.seq, "RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL"
            )
            self.assertEqual(
                alignment.query.seq, "RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.54)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.16)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "3659")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 2 (LOC101210909), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 2 (LOC101210909), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 37 aligned letters; 15 identities; 22 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 37:
        identities = 15,
        positives = 23,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|449492         0 RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL 37
                  0 |.||..|...|....|....|.|.|.|||..|.|..| 37
gi|296147         0 RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|449492804|ref|XM_004159058.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|449492804|ref|XM_004159058.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "449492804")
            self.assertEqual(alignment.target.annotations["gis"], "449492804")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004159058")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004159058")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004159058.1")
            self.assertEqual(alignment.target.annotations["length"], 2110)
            self.assertEqual(alignment.query.annotations["start"], 76)
            self.assertEqual(alignment.query.annotations["end"], 187)
            self.assertEqual(alignment.target.annotations["start"], 652)
            self.assertEqual(alignment.target.annotations["end"], 763)
            self.assertEqual(
                alignment.target.seq, "RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL"
            )
            self.assertEqual(
                alignment.query.seq, "RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.54)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.16)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "3659")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 1 (LOC101210909), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 1 (LOC101210909), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 37 aligned letters; 15 identities; 22 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 37:
        identities = 15,
        positives = 23,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|449443         0 RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL 37
                  0 |.||..|...|....|....|.|.|.|||..|.|..| 37
gi|296147         0 RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|449443485|ref|XM_004139460.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|449443485|ref|XM_004139460.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "449443485")
            self.assertEqual(alignment.target.annotations["gis"], "449443485")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004139460")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004139460")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004139460.1")
            self.assertEqual(alignment.target.annotations["length"], 1989)
            self.assertEqual(alignment.query.annotations["start"], 76)
            self.assertEqual(alignment.query.annotations["end"], 187)
            self.assertEqual(alignment.target.annotations["start"], 533)
            self.assertEqual(alignment.target.annotations["end"], 644)
            self.assertEqual(
                alignment.target.seq, "RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL"
            )
            self.assertEqual(
                alignment.query.seq, "RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.54)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.16)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "3659")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 2 (LOC101210909), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 2 (LOC101210909), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 37 aligned letters; 15 identities; 22 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 37:
        identities = 15,
        positives = 23,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|449443         0 RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL 37
                  0 |.||..|...|....|....|.|.|.|||..|.|..| 37
gi|296147         0 RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|449443483|ref|XM_004139459.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|449443483|ref|XM_004139459.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "449443483")
            self.assertEqual(alignment.target.annotations["gis"], "449443483")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004139459")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004139459")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004139459.1")
            self.assertEqual(alignment.target.annotations["length"], 2108)
            self.assertEqual(alignment.query.annotations["start"], 76)
            self.assertEqual(alignment.query.annotations["end"], 187)
            self.assertEqual(alignment.target.annotations["start"], 652)
            self.assertEqual(alignment.target.annotations["end"], 763)
            self.assertEqual(
                alignment.target.seq, "RLEEVSPLGSLLTGQLNRAREFIILKS*KTVRLSIEL"
            )
            self.assertEqual(
                alignment.query.seq, "RKEEIQPFAMLVINPLRY*KEYIVLRS*KDIRISHSL"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.54)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 22)
            self.assertEqual(alignment.annotations["positives"], 23)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 62.16)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "3659")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 1 (LOC101210909), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cucumis sativus uncharacterized LOC101210909, transcript variant 1 (LOC101210909), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 37 aligned letters; 15 identities; 22 mismatches; 23 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 37:
        identities = 15,
        positives = 23,
        mismatches = 22.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 22)
            self.assertEqual(counts.positives, 23)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|432873         0 CWLRSQGTTERRPLQMRSSADRAPSHFQMETAYLVFQM 38
                  0 |||..||....||.|.....|..|.|...|...|.|.| 38
gi|296147         0 CWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWM 38
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  38],
                              [  0,  38]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|432873290|ref|XM_004072130.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|432873290|ref|XM_004072130.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "432873290")
            self.assertEqual(alignment.target.annotations["gis"], "432873290")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004072130")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004072130")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004072130.1")
            self.assertEqual(alignment.target.annotations["length"], 6378)
            self.assertEqual(alignment.query.annotations["start"], 190)
            self.assertEqual(alignment.query.annotations["end"], 304)
            self.assertEqual(alignment.target.annotations["start"], 4027)
            self.assertEqual(alignment.target.annotations["end"], 3913)
            self.assertEqual(
                alignment.target.seq, "CWLRSQGTTERRPLQMRSSADRAPSHFQMETAYLVFQM"
            )
            self.assertEqual(
                alignment.query.seq, "CWLANQGMLK*RPWQCNAYRDCQPFHLFLEAGCLKFWM"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 38))
            self.assertAlmostEqual(alignment.annotations["% identity"], 39.47)
            self.assertEqual(alignment.annotations["identical"], 15)
            self.assertEqual(alignment.annotations["mismatches"], 23)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/-3")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "-3")
            self.assertEqual(alignment.target.annotations["tax ids"], "8090")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Oryzias latipes zinc finger protein 462-like (LOC101161246), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Oryzias latipes zinc finger protein 462-like (LOC101161246), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 33)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 33)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 38 aligned letters; 15 identities; 23 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 38:
        identities = 15,
        positives = 19,
        mismatches = 23.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 38)
            self.assertEqual(counts.identities, 15)
            self.assertEqual(counts.mismatches, 23)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|426392         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|426392076|ref|XM_004062338.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|426392076|ref|XM_004062338.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "426392076")
            self.assertEqual(alignment.target.annotations["gis"], "426392076")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004062338")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004062338")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004062338.1")
            self.assertEqual(alignment.target.annotations["length"], 9002)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 345)
            self.assertEqual(alignment.target.annotations["end"], 426)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9595")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Gorilla gorilla gorilla ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Gorilla gorilla gorilla ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410953         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410953779|ref|XM_003983499.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410953779|ref|XM_003983499.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410953779")
            self.assertEqual(alignment.target.annotations["gis"], "410953779")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003983499")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003983499")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003983499.1")
            self.assertEqual(alignment.target.annotations["length"], 6297)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 129)
            self.assertEqual(alignment.target.annotations["end"], 210)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9685")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Felis catus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Felis catus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|403282         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|403282318|ref|XM_003932550.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|403282318|ref|XM_003932550.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "403282318")
            self.assertEqual(alignment.target.annotations["gis"], "403282318")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003932550")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003932550")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003932550.1")
            self.assertEqual(alignment.target.annotations["length"], 7122)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 378)
            self.assertEqual(alignment.target.annotations["end"], 459)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "39432")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Saimiri boliviensis boliviensis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Saimiri boliviensis boliviensis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|402882         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|402882302|ref|XM_003904638.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|402882302|ref|XM_003904638.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "402882302")
            self.assertEqual(alignment.target.annotations["gis"], "402882302")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003904638")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003904638")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003904638.1")
            self.assertEqual(alignment.target.annotations["length"], 9027)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 378)
            self.assertEqual(alignment.target.annotations["end"], 459)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9555")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Papio anubis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Papio anubis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|397475         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|397475827|ref|XM_003809272.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|397475827|ref|XM_003809272.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "397475827")
            self.assertEqual(alignment.target.annotations["gis"], "397475827")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003809272")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003809272")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003809272.1")
            self.assertEqual(alignment.target.annotations["length"], 8939)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 282)
            self.assertEqual(alignment.target.annotations["end"], 363)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9597")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan paniscus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan paniscus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|395752         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|395752429|ref|XM_002830404.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|395752429|ref|XM_002830404.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "395752429")
            self.assertEqual(alignment.target.annotations["gis"], "395752429")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002830404")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002830404")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002830404.2")
            self.assertEqual(alignment.target.annotations["length"], 5544)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 345)
            self.assertEqual(alignment.target.annotations["end"], 426)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9601")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pongo abelii ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pongo abelii ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|395506         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|395506884|ref|XM_003757711.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|395506884|ref|XM_003757711.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "395506884")
            self.assertEqual(alignment.target.annotations["gis"], "395506884")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003757711")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003757711")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003757711.1")
            self.assertEqual(alignment.target.annotations["length"], 5767)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 153)
            self.assertEqual(alignment.target.annotations["end"], 234)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9305")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sarcophilus harrisii ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sarcophilus harrisii ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363741         0 YFLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363741618|ref|XM_417388.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363741618|ref|XM_417388.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363741618")
            self.assertEqual(alignment.target.annotations["gis"], "363741618")
            self.assertEqual(alignment.target.annotations["acc."], "XM_417388")
            self.assertEqual(alignment.target.annotations["accs."], "XM_417388")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_417388.3")
            self.assertEqual(alignment.target.annotations["length"], 5934)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 313)
            self.assertEqual(alignment.target.annotations["end"], 394)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/2")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9031")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Gallus gallus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Gallus gallus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|359322         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|359322761|ref|XM_534448.4|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|359322761|ref|XM_534448.4|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "359322761")
            self.assertEqual(alignment.target.annotations["gis"], "359322761")
            self.assertEqual(alignment.target.annotations["acc."], "XM_534448")
            self.assertEqual(alignment.target.annotations["accs."], "XM_534448")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_534448.4")
            self.assertEqual(alignment.target.annotations["length"], 6505)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 353)
            self.assertEqual(alignment.target.annotations["end"], 434)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9615")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Canis lupus familiaris ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Canis lupus familiaris ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|354476         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|354476751|ref|XM_003500539.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|354476751|ref|XM_003500539.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "354476751")
            self.assertEqual(alignment.target.annotations["gis"], "354476751")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003500539")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003500539")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003500539.1")
            self.assertEqual(alignment.target.annotations["length"], 6829)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 207)
            self.assertEqual(alignment.target.annotations["end"], 288)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "10029")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cricetulus griseus brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100773989), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cricetulus griseus brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100773989), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|350595         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|350595022|ref|XM_003483981.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350595022|ref|XM_003483981.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "350595022")
            self.assertEqual(alignment.target.annotations["gis"], "350595022")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003483981")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003483981")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003483981.1")
            self.assertEqual(alignment.target.annotations["length"], 6052)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 351)
            self.assertEqual(alignment.target.annotations["end"], 432)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9823")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sus scrofa ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sus scrofa ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|350591         0 AGRVDFWMPGLRLWPRRWRF 20
                  0 ||...||||.|||...|||| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|350591776|ref|XM_003132566.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350591776|ref|XM_003132566.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "350591776")
            self.assertEqual(alignment.target.annotations["gis"], "350591776")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003132566")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003132566")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003132566.3")
            self.assertEqual(alignment.target.annotations["length"], 1870)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 1159)
            self.assertEqual(alignment.target.annotations["end"], 1219)
            self.assertEqual(alignment.target.seq, "AGRVDFWMPGLRLWPRRWRF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9823")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sus scrofa ephrin type-B receptor 3-like (LOC100514541), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sus scrofa ephrin type-B receptor 3-like (LOC100514541), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|350591         0 AGRVDFWMPGLRLWPRRWRF 20
                  0 ||...||||.|||...|||| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|350591772|ref|XM_003358733.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350591772|ref|XM_003358733.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "350591772")
            self.assertEqual(alignment.target.annotations["gis"], "350591772")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003358733")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003358733")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003358733.2")
            self.assertEqual(alignment.target.annotations["length"], 3776)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 3064)
            self.assertEqual(alignment.target.annotations["end"], 3124)
            self.assertEqual(alignment.target.seq, "AGRVDFWMPGLRLWPRRWRF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9823")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sus scrofa EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sus scrofa EPH receptor B3, transcript variant 2 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|348563         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|348563932|ref|XM_003467713.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|348563932|ref|XM_003467713.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "348563932")
            self.assertEqual(alignment.target.annotations["gis"], "348563932")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003467713")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003467713")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003467713.1")
            self.assertEqual(alignment.target.annotations["length"], 5355)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "10141")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Cavia porcellus brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100724838), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Cavia porcellus brefeldin A-inhibited guanine nucleotide-exchange protein 2-like (LOC100724838), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|344280         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|344280063|ref|XM_003411757.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|344280063|ref|XM_003411757.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "344280063")
            self.assertEqual(alignment.target.annotations["gis"], "344280063")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003411757")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003411757")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003411757.1")
            self.assertEqual(alignment.target.annotations["length"], 5452)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9785")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Loxodonta africana ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Loxodonta africana ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|338719         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|338719107|ref|XM_001916930.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|338719107|ref|XM_001916930.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "338719107")
            self.assertEqual(alignment.target.annotations["gis"], "338719107")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001916930")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001916930")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001916930.2")
            self.assertEqual(alignment.target.annotations["length"], 5782)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 342)
            self.assertEqual(alignment.target.annotations["end"], 423)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9796")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Equus caballus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Equus caballus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|335300         0 AGRVDFWMPGLRLWPRRWRF 20
                  0 ||...||||.|||...|||| 20
gi|296147         0 AGCLKFWMPSLRLLISRWRF 20
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  20],
                              [  0,  20]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|335300059|ref|XM_003132565.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|335300059|ref|XM_003132565.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "335300059")
            self.assertEqual(alignment.target.annotations["gis"], "335300059")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003132565")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003132565")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003132565.2")
            self.assertEqual(alignment.target.annotations["length"], 3667)
            self.assertEqual(alignment.query.annotations["start"], 280)
            self.assertEqual(alignment.query.annotations["end"], 340)
            self.assertEqual(alignment.target.annotations["start"], 2956)
            self.assertEqual(alignment.target.annotations["end"], 3016)
            self.assertEqual(alignment.target.seq, "AGRVDFWMPGLRLWPRRWRF")
            self.assertEqual(alignment.query.seq, "AGCLKFWMPSLRLLISRWRF")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 20))
            self.assertAlmostEqual(alignment.annotations["% identity"], 65.00)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 7)
            self.assertEqual(alignment.annotations["positives"], 14)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.00)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "2/2")
            self.assertEqual(alignment.query.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["frame"], "2")
            self.assertEqual(alignment.target.annotations["tax ids"], "9823")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sus scrofa EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sus scrofa EPH receptor B3, transcript variant 1 (EPHB3), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 17)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 17)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 20 aligned letters; 13 identities; 7 mismatches; 14 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 20:
        identities = 13,
        positives = 14,
        mismatches = 7.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 20)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 7)
            self.assertEqual(counts.positives, 14)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|334312         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|334312365|ref|XM_001379067.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|334312365|ref|XM_001379067.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "334312365")
            self.assertEqual(alignment.target.annotations["gis"], "334312365")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001379067")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001379067")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001379067.2")
            self.assertEqual(alignment.target.annotations["length"], 5511)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "13616")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Monodelphis domestica ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Monodelphis domestica ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332858         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332858727|ref|XM_001165517.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332858727|ref|XM_001165517.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332858727")
            self.assertEqual(alignment.target.annotations["gis"], "332858727")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001165517")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001165517")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001165517.2")
            self.assertEqual(alignment.target.annotations["length"], 8850)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 1 (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 1 (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332207         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332207745|ref|XM_003252909.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332207745|ref|XM_003252909.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332207745")
            self.assertEqual(alignment.target.annotations["gis"], "332207745")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003252909")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003252909")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003252909.1")
            self.assertEqual(alignment.target.annotations["length"], 9022)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 369)
            self.assertEqual(alignment.target.annotations["end"], 450)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "61853")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Nomascus leucogenys ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 2 (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Nomascus leucogenys ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 2 (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|332207         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|332207743|ref|XM_003252908.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|332207743|ref|XM_003252908.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "332207743")
            self.assertEqual(alignment.target.annotations["gis"], "332207743")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003252908")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003252908")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003252908.1")
            self.assertEqual(alignment.target.annotations["length"], 9031)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 369)
            self.assertEqual(alignment.target.annotations["end"], 450)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "61853")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Nomascus leucogenys ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 1 (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Nomascus leucogenys ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 1 (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|326931         0 YFLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|326931872|ref|XM_003212000.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|326931872|ref|XM_003212000.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "326931872")
            self.assertEqual(alignment.target.annotations["gis"], "326931872")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003212000")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003212000")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003212000.1")
            self.assertEqual(alignment.target.annotations["length"], 5240)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 80)
            self.assertEqual(alignment.target.annotations["end"], 161)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9103")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Meleagris gallopavo ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Meleagris gallopavo ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|327271         0 YFLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|327271833|ref|XM_003220644.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|327271833|ref|XM_003220644.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "327271833")
            self.assertEqual(alignment.target.annotations["gis"], "327271833")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003220644")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003220644")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003220644.1")
            self.assertEqual(alignment.target.annotations["length"], 5379)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 219)
            self.assertEqual(alignment.target.annotations["end"], 300)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "28377")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Anolis carolinensis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Anolis carolinensis ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (arfgef2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|301754         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|301754408|ref|XM_002912990.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|301754408|ref|XM_002912990.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "301754408")
            self.assertEqual(alignment.target.annotations["gis"], "301754408")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002912990")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002912990")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002912990.1")
            self.assertEqual(alignment.target.annotations["length"], 6451)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9646")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Ailuropoda melanoleuca ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Ailuropoda melanoleuca ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|297259         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|297259620|ref|XM_002798127.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|297259620|ref|XM_002798127.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "297259620")
            self.assertEqual(alignment.target.annotations["gis"], "297259620")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002798127")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002798127")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002798127.1")
            self.assertEqual(alignment.target.annotations["length"], 5801)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 378)
            self.assertEqual(alignment.target.annotations["end"], 459)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9544")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Macaca mulatta ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Macaca mulatta ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|296200         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|296200663|ref|XM_002806776.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|296200663|ref|XM_002806776.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "296200663")
            self.assertEqual(alignment.target.annotations["gis"], "296200663")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002806776")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002806776")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002806776.1")
            self.assertEqual(alignment.target.annotations["length"], 5612)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 240)
            self.assertEqual(alignment.target.annotations["end"], 321)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9483")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Callithrix jacchus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Callithrix jacchus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|242009         0 YFLPFELVCQSKSSRIVVTALDCLQKL 27
                  0 ..|||.|.|||........|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|242009078|ref|XM_002425275.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|242009078|ref|XM_002425275.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "242009078")
            self.assertEqual(alignment.target.annotations["gis"], "242009078")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002425275")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002425275")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002425275.1")
            self.assertEqual(alignment.target.annotations["length"], 5343)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 225)
            self.assertEqual(alignment.target.annotations["end"], 306)
            self.assertEqual(alignment.target.seq, "YFLPFELVCQSKSSRIVVTALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "121224")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Pediculus humanus corporis Brefeldin A-inhibited guanine nucleotide-exchange protein, putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Pediculus humanus corporis Brefeldin A-inhibited guanine nucleotide-exchange protein, putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 19,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|224078         0 YFLPFELACQSKSPRIVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|224078727|ref|XM_002187178.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|224078727|ref|XM_002187178.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "224078727")
            self.assertEqual(alignment.target.annotations["gis"], "224078727")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002187178")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002187178")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002187178.1")
            self.assertEqual(alignment.target.annotations["length"], 5406)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 219)
            self.assertEqual(alignment.target.annotations["end"], 300)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "59729")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Taeniopygia guttata ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Taeniopygia guttata ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|167736         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|167736368|ref|NM_001085495.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|167736368|ref|NM_001085495.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "167736368")
            self.assertEqual(alignment.target.annotations["gis"], "167736368")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001085495")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001085495")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001085495.2")
            self.assertEqual(alignment.target.annotations["length"], 8777)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 335)
            self.assertEqual(alignment.target.annotations["end"], 416)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "10090")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Mus musculus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Mus musculus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|150417         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|150417985|ref|NM_006420.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|150417985|ref|NM_006420.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "150417985")
            self.assertEqual(alignment.target.annotations["gis"], "150417985")
            self.assertEqual(alignment.target.annotations["acc."], "NM_006420")
            self.assertEqual(alignment.target.annotations["accs."], "NM_006420")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_006420.2")
            self.assertEqual(alignment.target.annotations["length"], 9004)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 353)
            self.assertEqual(alignment.target.annotations["end"], 434)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9606")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Homo sapiens ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Homo sapiens ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|149639         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|149639802|ref|XM_001506842.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|149639802|ref|XM_001506842.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "149639802")
            self.assertEqual(alignment.target.annotations["gis"], "149639802")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001506842")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001506842")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001506842.1")
            self.assertEqual(alignment.target.annotations["length"], 5268)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 105)
            self.assertEqual(alignment.target.annotations["end"], 186)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9258")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Ornithorhynchus anatinus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Ornithorhynchus anatinus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|114682         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|114682530|ref|XM_001165584.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|114682530|ref|XM_001165584.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "114682530")
            self.assertEqual(alignment.target.annotations["gis"], "114682530")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001165584")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001165584")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001165584.1")
            self.assertEqual(alignment.target.annotations["length"], 8859)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 3 (ARFGEF2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited), transcript variant 3 (ARFGEF2), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|313420         0 YFLPFELACQSKSPRVVSTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|31342050|ref|NM_181083.2|")
            self.assertEqual(
                alignment.target.annotations["ids"],
                "gi|31342050|ref|NM_181083.2|;gi|31126987|gb|AY255526.2|",
            )
            self.assertEqual(alignment.target.annotations["gi"], "31342050")
            self.assertEqual(alignment.target.annotations["gis"], "31342050;31126987")
            self.assertEqual(alignment.target.annotations["acc."], "NM_181083")
            self.assertEqual(
                alignment.target.annotations["accs."], "NM_181083;AY255526"
            )
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_181083.2")
            self.assertEqual(alignment.target.annotations["length"], 5784)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 201)
            self.assertEqual(alignment.target.annotations["end"], 282)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRVVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 6.4)
            self.assertAlmostEqual(alignment.annotations["bit score"], 35.0)
            self.assertAlmostEqual(alignment.score, 70)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 74.07)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "10116")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Rattus norvegicus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Rattus norvegicus ADP-ribosylation factor guanine nucleotide-exchange factor 2 (brefeldin A-inhibited) (Arfgef2), mRNA<>Rattus norvegicus Brefeldin A-inhibited guanine nucleotide-exchange factor 2 (Big2) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 70.0; 27 aligned letters; 12 identities; 15 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 70.0,
    aligned = 27:
        identities = 12,
        positives = 20,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410036         0 RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL 55
                  0 |||........|....|.|...|......|..|....||..||||.||.|.|..| 55
gi|296147         0 RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410036861|ref|XM_001150377.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410036861|ref|XM_001150377.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410036861")
            self.assertEqual(alignment.target.annotations["gis"], "410036861")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001150377")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001150377")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001150377.3")
            self.assertEqual(alignment.target.annotations["length"], 3555)
            self.assertEqual(alignment.query.annotations["start"], 135)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 660)
            self.assertEqual(alignment.target.annotations["end"], 825)
            self.assertEqual(
                alignment.target.seq,
                "RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL",
            )
            self.assertEqual(
                alignment.query.seq,
                "RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.36)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.91)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes lactotransferrin, transcript variant 3 (LTF), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes lactotransferrin, transcript variant 3 (LTF), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 55 aligned letters; 20 identities; 35 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 55:
        identities = 20,
        positives = 28,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|410036         0 RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL 55
                  0 |||........|....|.|...|......|..|....||..||||.||.|.|..| 55
gi|296147         0 RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|410036860|ref|XM_516417.4|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|410036860|ref|XM_516417.4|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "410036860")
            self.assertEqual(alignment.target.annotations["gis"], "410036860")
            self.assertEqual(alignment.target.annotations["acc."], "XM_516417")
            self.assertEqual(alignment.target.annotations["accs."], "XM_516417")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_516417.4")
            self.assertEqual(alignment.target.annotations["length"], 3660)
            self.assertEqual(alignment.query.annotations["start"], 135)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 765)
            self.assertEqual(alignment.target.annotations["end"], 930)
            self.assertEqual(
                alignment.target.seq,
                "RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL",
            )
            self.assertEqual(
                alignment.query.seq,
                "RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.36)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.91)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9598")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan troglodytes lactotransferrin, transcript variant 8 (LTF), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan troglodytes lactotransferrin, transcript variant 8 (LTF), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 55 aligned letters; 20 identities; 35 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 55:
        identities = 20,
        positives = 28,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|397495         0 RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL 55
                  0 |||........|....|.|...|......|..|....||..||||.||.|.|..| 55
gi|296147         0 RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|397495317|ref|XM_003818457.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|397495317|ref|XM_003818457.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "397495317")
            self.assertEqual(alignment.target.annotations["gis"], "397495317")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003818457")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003818457")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003818457.1")
            self.assertEqual(alignment.target.annotations["length"], 2515)
            self.assertEqual(alignment.query.annotations["start"], 135)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 660)
            self.assertEqual(alignment.target.annotations["end"], 825)
            self.assertEqual(
                alignment.target.seq,
                "RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL",
            )
            self.assertEqual(
                alignment.query.seq,
                "RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.36)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.91)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9597")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan paniscus lactotransferrin, transcript variant 2 (LTF), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan paniscus lactotransferrin, transcript variant 2 (LTF), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 55 aligned letters; 20 identities; 35 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 55:
        identities = 20,
        positives = 28,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|397495         0 RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL 55
                  0 |||........|....|.|...|......|..|....||..||||.||.|.|..| 55
gi|296147         0 RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL 55
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  55],
                              [  0,  55]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|397495315|ref|XM_003818456.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|397495315|ref|XM_003818456.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "397495315")
            self.assertEqual(alignment.target.annotations["gis"], "397495315")
            self.assertEqual(alignment.target.annotations["acc."], "XM_003818456")
            self.assertEqual(alignment.target.annotations["accs."], "XM_003818456")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_003818456.1")
            self.assertEqual(alignment.target.annotations["length"], 2620)
            self.assertEqual(alignment.query.annotations["start"], 135)
            self.assertEqual(alignment.query.annotations["end"], 300)
            self.assertEqual(alignment.target.annotations["start"], 765)
            self.assertEqual(alignment.target.annotations["end"], 930)
            self.assertEqual(
                alignment.target.seq,
                "RVHLSPLRQLWPGSSQPAVFPVQIKDSSPTCVACVRGQGKTTVPSPPRNRTSATL",
            )
            self.assertEqual(
                alignment.query.seq,
                "RVHSFEELERHPDFALPFVLACQSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEIL",
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 55))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.36)
            self.assertEqual(alignment.annotations["identical"], 20)
            self.assertEqual(alignment.annotations["mismatches"], 35)
            self.assertEqual(alignment.annotations["positives"], 28)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 50.91)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9597")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Pan paniscus lactotransferrin, transcript variant 1 (LTF), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Pan paniscus lactotransferrin, transcript variant 1 (LTF), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 47)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 47)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 55 aligned letters; 20 identities; 35 mismatches; 28 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 55:
        identities = 20,
        positives = 28,
        mismatches = 35.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 55)
            self.assertEqual(counts.identities, 20)
            self.assertEqual(counts.mismatches, 35)
            self.assertEqual(counts.positives, 28)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|392887         0 YFLPFELACNSKSPKIVITALDCLQKL 27
                  0 ..|||.|||.|...|....|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|392887648|ref|NM_001026628.3|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|392887648|ref|NM_001026628.3|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "392887648")
            self.assertEqual(alignment.target.annotations["gis"], "392887648")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001026628")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001026628")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001026628.3")
            self.assertEqual(alignment.target.annotations["length"], 1656)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 234)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(alignment.target.seq, "YFLPFELACNSKSPKIVITALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "6239")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Caenorhabditis elegans Protein AGEF-1, isoform b (agef-1) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Caenorhabditis elegans Protein AGEF-1, isoform b (agef-1) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 13 identities; 14 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 13,
        positives = 18,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|392887         0 YFLPFELACNSKSPKIVITALDCLQKL 27
                  0 ..|||.|||.|...|....|..|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|392887646|ref|NM_001026627.5|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|392887646|ref|NM_001026627.5|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "392887646")
            self.assertEqual(alignment.target.annotations["gis"], "392887646")
            self.assertEqual(alignment.target.annotations["acc."], "NM_001026627")
            self.assertEqual(alignment.target.annotations["accs."], "NM_001026627")
            self.assertEqual(alignment.target.annotations["acc.ver"], "NM_001026627.5")
            self.assertEqual(alignment.target.annotations["length"], 4785)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 234)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(alignment.target.seq, "YFLPFELACNSKSPKIVITALDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 18)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 66.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "6239")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Caenorhabditis elegans Protein AGEF-1, isoform a",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Caenorhabditis elegans Protein AGEF-1, isoform a",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 13 identities; 14 mismatches; 18 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 13,
        positives = 18,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 18)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|363727         0 NIGTMWNLQWEFKR*FSFSSRDDRRDPATSCQCMEGFLSLFCA 43
                  0 ||.....|.|.......|.|.|..|..|.||.|||.....|.| 43
gi|296147         0 NISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA 43
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  43],
                              [  0,  43]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|363727654|ref|XM_001235329.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|363727654|ref|XM_001235329.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "363727654")
            self.assertEqual(alignment.target.annotations["gis"], "363727654")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001235329")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001235329")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001235329.2")
            self.assertEqual(alignment.target.annotations["length"], 8058)
            self.assertEqual(alignment.query.annotations["start"], 131)
            self.assertEqual(alignment.query.annotations["end"], 2)
            self.assertEqual(alignment.target.annotations["start"], 1805)
            self.assertEqual(alignment.target.annotations["end"], 1934)
            self.assertEqual(
                alignment.target.seq, "NIGTMWNLQWEFKR*FSFSSRDDRRDPATSCQCMEGFLSLFCA"
            )
            self.assertEqual(
                alignment.query.seq, "NISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMESNPPVFMA"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 43))
            self.assertAlmostEqual(alignment.annotations["% identity"], 37.21)
            self.assertEqual(alignment.annotations["identical"], 16)
            self.assertEqual(alignment.annotations["mismatches"], 27)
            self.assertEqual(alignment.annotations["positives"], 20)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 46.51)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/3")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9031")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Gallus gallus otogelin-like (LOC772154), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Gallus gallus otogelin-like (LOC772154), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 37)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 37)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 43 aligned letters; 16 identities; 27 mismatches; 20 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 43:
        identities = 16,
        positives = 20,
        mismatches = 27.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 43)
            self.assertEqual(counts.identities, 16)
            self.assertEqual(counts.mismatches, 27)
            self.assertEqual(counts.positives, 20)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|350583         0 YFLPFELACQSRCPRIVSTSLDCLQKL 27
                  0 ..|||.||||||..........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|350583133|ref|XM_001928010.4|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|350583133|ref|XM_001928010.4|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "350583133")
            self.assertEqual(alignment.target.annotations["gis"], "350583133")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001928010")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001928010")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001928010.4")
            self.assertEqual(alignment.target.annotations["length"], 7207)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 584)
            self.assertEqual(alignment.target.annotations["end"], 665)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRCPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/3")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "9823")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Sus scrofa guanine nucleotide-exchange protein (LOC100156861), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Sus scrofa guanine nucleotide-exchange protein (LOC100156861), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|345486         0 YFLPFELACQSKSPRIVVTSLDCLQKL 27
                  0 ..|||.|||||...........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|345486369|ref|XM_001605920.2|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|345486369|ref|XM_001605920.2|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "345486369")
            self.assertEqual(alignment.target.annotations["gis"], "345486369")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001605920")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001605920")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001605920.2")
            self.assertEqual(alignment.target.annotations["length"], 7150)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 234)
            self.assertEqual(alignment.target.annotations["end"], 315)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSKSPRIVVTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 44.44)
            self.assertEqual(alignment.annotations["identical"], 12)
            self.assertEqual(alignment.annotations["mismatches"], 15)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7425")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Nasonia vitripennis brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100122365), mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Nasonia vitripennis brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100122365), mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 12 identities; 15 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 12,
        positives = 19,
        mismatches = 15.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 12)
            self.assertEqual(counts.mismatches, 15)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|344272         0 YFLPFELACQSRCPRIVSTSLDCLQKL 27
                  0 ..|||.||||||..........|||.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|344272888|ref|XR_133687.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|344272888|ref|XR_133687.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "344272888")
            self.assertEqual(alignment.target.annotations["gis"], "344272888")
            self.assertEqual(alignment.target.annotations["acc."], "XR_133687")
            self.assertEqual(alignment.target.annotations["accs."], "XR_133687")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XR_133687.1")
            self.assertEqual(alignment.target.annotations["length"], 5928)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 237)
            self.assertEqual(alignment.target.annotations["end"], 318)
            self.assertEqual(alignment.target.seq, "YFLPFELACQSRCPRIVSTSLDCLQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 48.15)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 14)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "9785")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "PREDICTED: Loxodonta africana brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100676028), miscRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "PREDICTED: Loxodonta africana brefeldin A-inhibited guanine nucleotide-exchange protein 1-like (LOC100676028), miscRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 13 identities; 14 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 13,
        positives = 19,
        mismatches = 14.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 14)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|241632         0 YLMPFELACQSKSPRIVVTALDCIQKL 27
                  0 ...||.|||||........|..|.|.| 27
gi|296147         0 FALPFVLACQSRNAKMTTLAMQCLQGL 27
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  27],
                              [  0,  27]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|241632443|ref|XM_002408552.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|241632443|ref|XM_002408552.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "241632443")
            self.assertEqual(alignment.target.annotations["gis"], "241632443")
            self.assertEqual(alignment.target.annotations["acc."], "XM_002408552")
            self.assertEqual(alignment.target.annotations["accs."], "XM_002408552")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_002408552.1")
            self.assertEqual(alignment.target.annotations["length"], 4938)
            self.assertEqual(alignment.query.annotations["start"], 174)
            self.assertEqual(alignment.query.annotations["end"], 255)
            self.assertEqual(alignment.target.annotations["start"], 231)
            self.assertEqual(alignment.target.annotations["end"], 312)
            self.assertEqual(alignment.target.seq, "YLMPFELACQSKSPRIVVTALDCIQKL")
            self.assertEqual(alignment.query.seq, "FALPFVLACQSRNAKMTTLAMQCLQGL")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 27))
            self.assertAlmostEqual(alignment.annotations["% identity"], 40.74)
            self.assertEqual(alignment.annotations["identical"], 11)
            self.assertEqual(alignment.annotations["mismatches"], 16)
            self.assertEqual(alignment.annotations["positives"], 19)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 70.37)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "6945")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Ixodes scapularis brefeldin A-inhibited guanine nucleotide-exchange protein, putative, mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Ixodes scapularis brefeldin A-inhibited guanine nucleotide-exchange protein, putative, mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 23)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 23)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 27 aligned letters; 11 identities; 16 mismatches; 19 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 27:
        identities = 11,
        positives = 19,
        mismatches = 16.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 27)
            self.assertEqual(counts.identities, 11)
            self.assertEqual(counts.mismatches, 16)
            self.assertEqual(counts.positives, 19)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|157129         0 QAYNMSVTDLAIKSIQGIASLHTLPRSRAIIAFQAFV 37
                  0 |..|...|.||....||.......||||......||. 37
gi|296147         0 QSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|157129065|ref|XM_001655210.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|157129065|ref|XM_001655210.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "157129065")
            self.assertEqual(alignment.target.annotations["gis"], "157129065")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001655210")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001655210")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001655210.1")
            self.assertEqual(alignment.target.annotations["length"], 3194)
            self.assertEqual(alignment.query.annotations["start"], 201)
            self.assertEqual(alignment.query.annotations["end"], 312)
            self.assertEqual(alignment.target.annotations["start"], 1116)
            self.assertEqual(alignment.target.annotations["end"], 1227)
            self.assertEqual(
                alignment.target.seq, "QAYNMSVTDLAIKSIQGIASLHTLPRSRAIIAFQAFV"
            )
            self.assertEqual(
                alignment.query.seq, "QSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.14)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 25)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.57)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7159")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aedes aegypti hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aedes aegypti hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 37 aligned letters; 13 identities; 24 mismatches; 25 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 37:
        identities = 13,
        positives = 25,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 25)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|157129         0 QAYNMSVTDLAIKSIQGIASLHTLPRSRAIIAFQAFV 37
                  0 |..|...|.||....||.......||||......||. 37
gi|296147         0 QSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI 37
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  37],
                              [  0,  37]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|157129063|ref|XM_001655209.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|157129063|ref|XM_001655209.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "157129063")
            self.assertEqual(alignment.target.annotations["gis"], "157129063")
            self.assertEqual(alignment.target.annotations["acc."], "XM_001655209")
            self.assertEqual(alignment.target.annotations["accs."], "XM_001655209")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_001655209.1")
            self.assertEqual(alignment.target.annotations["length"], 3108)
            self.assertEqual(alignment.query.annotations["start"], 201)
            self.assertEqual(alignment.query.annotations["end"], 312)
            self.assertEqual(alignment.target.annotations["start"], 1116)
            self.assertEqual(alignment.target.annotations["end"], 1227)
            self.assertEqual(
                alignment.target.seq, "QAYNMSVTDLAIKSIQGIASLHTLPRSRAIIAFQAFV"
            )
            self.assertEqual(
                alignment.query.seq, "QSRNAKMTTLAMQCLQGLSTVPSIPRSRLSEILDAFI"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.7)
            self.assertAlmostEqual(alignment.annotations["bit score"], 34.5)
            self.assertAlmostEqual(alignment.score, 69)
            self.assertEqual(alignment.shape, (2, 37))
            self.assertAlmostEqual(alignment.annotations["% identity"], 35.14)
            self.assertEqual(alignment.annotations["identical"], 13)
            self.assertEqual(alignment.annotations["mismatches"], 24)
            self.assertEqual(alignment.annotations["positives"], 25)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 67.57)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "1/1")
            self.assertEqual(alignment.query.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "7159")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Aedes aegypti hypothetical protein partial mRNA",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Aedes aegypti hypothetical protein partial mRNA",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 32)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 32)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 69.0; 37 aligned letters; 13 identities; 24 mismatches; 25 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 69.0,
    aligned = 37:
        identities = 13,
        positives = 25,
        mismatches = 24.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 37)
            self.assertEqual(counts.identities, 13)
            self.assertEqual(counts.mismatches, 24)
            self.assertEqual(counts.positives, 25)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470250         0 HSQIGNPSTNNNNNQNLITQPQNYEMYKIN 30
                  0 ||.||.|......|......||||....|. 30
gi|296147         0 HSLIGKPTRKGVRNPDVFLAPQNYVLFSIS 30
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  30],
                              [  0,  30]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470250072|ref|XM_004367211.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470250072|ref|XM_004367211.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470250072")
            self.assertEqual(alignment.target.annotations["gis"], "470250072")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004367211")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004367211")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004367211.1")
            self.assertEqual(alignment.target.annotations["length"], 1509)
            self.assertEqual(alignment.query.annotations["start"], 214)
            self.assertEqual(alignment.query.annotations["end"], 124)
            self.assertEqual(alignment.target.annotations["start"], 1083)
            self.assertEqual(alignment.target.annotations["end"], 1173)
            self.assertEqual(alignment.target.seq, "HSQIGNPSTNNNNNQNLITQPQNYEMYKIN")
            self.assertEqual(alignment.query.seq, "HSLIGKPTRKGVRNPDVFLAPQNYVLFSIS")
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 31.3)
            self.assertAlmostEqual(alignment.score, 62)
            self.assertEqual(alignment.shape, (2, 30))
            self.assertAlmostEqual(alignment.annotations["% identity"], 36.67)
            self.assertEqual(alignment.annotations["identical"], 11)
            self.assertEqual(alignment.annotations["mismatches"], 19)
            self.assertEqual(alignment.annotations["positives"], 17)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 56.67)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-2/1")
            self.assertEqual(alignment.query.annotations["frame"], "-2")
            self.assertEqual(alignment.target.annotations["frame"], "1")
            self.assertEqual(alignment.target.annotations["tax ids"], "261658")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Dictyostelium fasciculatum hypothetical protein (DFA_07408) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Dictyostelium fasciculatum hypothetical protein (DFA_07408) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 55)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 26)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 62.0; 30 aligned letters; 11 identities; 19 mismatches; 17 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 62.0,
    aligned = 30:
        identities = 11,
        positives = 17,
        mismatches = 19.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 30)
            self.assertEqual(counts.identities, 11)
            self.assertEqual(counts.mismatches, 19)
            self.assertEqual(counts.positives, 17)
            alignment = next(alignments)
            self.assertEqual(
                str(alignment),
                """\
gi|470250         0 LFQEKTSLS*LWKVILFTML*SPSHCTRLPTQCPCLRS 38
                  0 ||.....||..|....|....|..........|.|..| 38
gi|296147         0 LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMES 38
""",
            )
            self.assertTrue(
                np.array_equal(
                    alignment.coordinates,
                    # fmt: off
                    np.array([[  0,  38],
                              [  0,  38]])
                    # fmt: on
                )
            )
            self.assertEqual(alignment.query.id, "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.description,
                "Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds",
            )
            self.assertEqual(alignment.query.annotations["gi"], "0")
            self.assertEqual(alignment.query.annotations["acc."], "gi|296147483:1-350")
            self.assertEqual(
                alignment.query.annotations["acc.ver"], "gi|296147483:1-350"
            )
            self.assertEqual(alignment.target.id, "gi|470250072|ref|XM_004367211.1|")
            self.assertEqual(
                alignment.target.annotations["ids"], "gi|470250072|ref|XM_004367211.1|"
            )
            self.assertEqual(alignment.target.annotations["gi"], "470250072")
            self.assertEqual(alignment.target.annotations["gis"], "470250072")
            self.assertEqual(alignment.target.annotations["acc."], "XM_004367211")
            self.assertEqual(alignment.target.annotations["accs."], "XM_004367211")
            self.assertEqual(alignment.target.annotations["acc.ver"], "XM_004367211.1")
            self.assertEqual(alignment.target.annotations["length"], 1509)
            self.assertEqual(alignment.query.annotations["start"], 137)
            self.assertEqual(alignment.query.annotations["end"], 23)
            self.assertEqual(alignment.target.annotations["start"], 1298)
            self.assertEqual(alignment.target.annotations["end"], 1412)
            self.assertEqual(
                alignment.target.seq, "LFQEKTSLS*LWKVILFTML*SPSHCTRLPTQCPCLRS"
            )
            self.assertEqual(
                alignment.query.seq, "LFNISMDLSLAWRMVEFLLFDSEDKERNSASSCLCMES"
            )
            self.assertAlmostEqual(alignment.annotations["evalue"], 8.8)
            self.assertAlmostEqual(alignment.annotations["bit score"], 22.1)
            self.assertAlmostEqual(alignment.score, 42)
            self.assertEqual(alignment.shape, (2, 38))
            self.assertAlmostEqual(alignment.annotations["% identity"], 26.32)
            self.assertEqual(alignment.annotations["identical"], 10)
            self.assertEqual(alignment.annotations["mismatches"], 28)
            self.assertEqual(alignment.annotations["positives"], 16)
            self.assertEqual(alignment.annotations["gap opens"], 0)
            self.assertEqual(alignment.annotations["gaps"], 0)
            self.assertAlmostEqual(alignment.annotations["% positives"], 42.11)
            self.assertEqual(alignment.annotations["query/sbjct frames"], "-1/3")
            self.assertEqual(alignment.query.annotations["frame"], "-1")
            self.assertEqual(alignment.target.annotations["frame"], "3")
            self.assertEqual(alignment.target.annotations["tax ids"], "261658")
            self.assertEqual(alignment.target.annotations["sci names"], "N/A")
            self.assertEqual(alignment.target.annotations["com names"], "N/A")
            self.assertEqual(alignment.target.annotations["blast names"], "N/A")
            self.assertEqual(alignment.target.annotations["super kingdoms"], "N/A")
            self.assertEqual(
                alignment.target.annotations["title"],
                "Dictyostelium fasciculatum hypothetical protein (DFA_07408) mRNA, complete cds",
            )
            self.assertEqual(
                alignment.target.annotations["titles"],
                "Dictyostelium fasciculatum hypothetical protein (DFA_07408) mRNA, complete cds",
            )
            self.assertEqual(alignment.target.annotations["strand"], "N/A")
            self.assertAlmostEqual(alignment.target.annotations["% coverage"], 55)
            self.assertAlmostEqual(alignment.annotations["% hsp coverage"], 33)
            counts = alignment.counts(substitution_matrix)
            self.assertEqual(
                repr(counts),
                "<AlignmentCounts object (substitution score = 42.0; 38 aligned letters; 10 identities; 28 mismatches; 16 positives; 0 gaps) at 0x%x>"
                % id(counts),
            )
            self.assertEqual(
                str(counts),
                """\
AlignmentCounts object with
    substitution_score = 42.0,
    aligned = 38:
        identities = 10,
        positives = 16,
        mismatches = 28.
    gaps = 0:
        left_gaps = 0:
            left_insertions = 0:
                open_left_insertions = 0,
                extend_left_insertions = 0;
            left_deletions = 0:
                open_left_deletions = 0,
                extend_left_deletions = 0;
        internal_gaps = 0:
            internal_insertions = 0:
                open_internal_insertions = 0,
                extend_internal_insertions = 0;
            internal_deletions = 0:
                open_internal_deletions = 0,
                extend_internal_deletions = 0;
        right_gaps = 0:
            right_insertions = 0:
                open_right_insertions = 0,
                extend_right_insertions = 0;
            right_deletions = 0:
                open_right_deletions = 0,
                extend_right_deletions = 0.
""",
            )
            self.assertEqual(counts.left_insertions, 0)
            self.assertEqual(counts.left_deletions, 0)
            self.assertEqual(counts.right_insertions, 0)
            self.assertEqual(counts.right_deletions, 0)
            self.assertEqual(counts.internal_insertions, 0)
            self.assertEqual(counts.internal_deletions, 0)
            self.assertEqual(counts.left_gaps, 0)
            self.assertEqual(counts.right_gaps, 0)
            self.assertEqual(counts.internal_gaps, 0)
            self.assertEqual(counts.insertions, 0)
            self.assertEqual(counts.deletions, 0)
            self.assertEqual(counts.gaps, 0)
            self.assertEqual(counts.aligned, 38)
            self.assertEqual(counts.identities, 10)
            self.assertEqual(counts.mismatches, 28)
            self.assertEqual(counts.positives, 16)
            with self.assertRaises(StopIteration):
                next(alignments)


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