# 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 Array in the Bio.Align.substitution_matrices module."""

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

    raise MissingExternalDependencyError(
        "Install NumPy if you want to use Bio.Align.substitution_matrices."
    ) from None


import os
import pickle
import unittest
from collections import Counter

from Bio import SeqIO
from Bio.Align import substitution_matrices
from Bio.Data import IUPACData

nucleotide_alphabet = IUPACData.unambiguous_dna_letters
protein_alphabet = IUPACData.protein_letters


class TestBasics(unittest.TestCase):
    def test_basics_vector(self):
        """Test basic vector operations."""
        counts = substitution_matrices.Array("XYZ")
        self.assertEqual(
            str(counts),
            """\
X 0.0
Y 0.0
Z 0.0
""",
        )
        self.assertEqual(counts.alphabet, "XYZ")
        counts["X"] = -9
        counts[2] = 5.5
        self.assertEqual(
            str(counts),
            """\
X -9.0
Y  0.0
Z  5.5
""",
        )
        self.assertAlmostEqual(counts[0], -9)
        with self.assertRaises(IndexError):
            counts["U"]
        with self.assertRaises(IndexError):
            counts["V"] = 3.0
        with self.assertRaises(IndexError):
            counts[8]

    def test_basics_matrix(self):
        """Test basic matrix operations."""
        counts = substitution_matrices.Array("XYZ", dims=2)
        self.assertEqual(
            str(counts),
            """\
    X   Y   Z
X 0.0 0.0 0.0
Y 0.0 0.0 0.0
Z 0.0 0.0 0.0
""",
        )
        counts["X", "Z"] = 12.0
        counts[2, 1] = 3.0
        counts["Y", 0] = -2.0
        counts[0, "Y"] = 5.0
        self.assertEqual(
            str(counts),
            """\
     X   Y    Z
X  0.0 5.0 12.0
Y -2.0 0.0  0.0
Z  0.0 3.0  0.0
""",
        )
        with self.assertRaises(IndexError):
            counts["U", 1]
        with self.assertRaises(IndexError):
            counts["X", 5]
        self.assertEqual(
            str(counts["Y"]),
            """\
X -2.0
Y  0.0
Z  0.0
""",
        )
        self.assertEqual(
            str(counts[:, "Z"]),
            """\
X 12.0
Y  0.0
Z  0.0
""",
        )

    def test_read_write(self):
        """Test reading and writing substitution matrices."""
        path = os.path.join("Align", "hg38.chrom.sizes")
        sizes = substitution_matrices.read(path, np.int64)
        # Note that sum(sizes) below is larger than 2147483647, and won't
        # fit in an int on a 32-bits machine.
        self.assertEqual(len(sizes), 455)
        self.assertEqual(sizes["chr1"], 248956422)
        self.assertEqual(sizes["chr2"], 242193529)
        self.assertEqual(sizes["chr3"], 198295559)
        self.assertEqual(sizes["chr4"], 190214555)
        self.assertEqual(sizes["chr5"], 181538259)
        self.assertEqual(sum(sizes), 3209286105)
        text = str(sizes)
        lines = text.split("\n")
        self.assertEqual(lines[0], "chr1 248956422")
        self.assertEqual(lines[1], "chr2 242193529")
        self.assertEqual(lines[2], "chr3 198295559")
        self.assertEqual(lines[3], "chr4 190214555")
        self.assertEqual(lines[4], "chr5 181538259")

    def test_nucleotide_freq(self):
        """Test nucleotide frequency calculations."""
        counts = Counter()
        path = os.path.join("Align", "ecoli.fa")
        records = SeqIO.parse(path, "fasta")
        for record in records:
            for nucleotide in record.seq:
                counts[nucleotide] += 1
        letters = sorted(counts.keys())
        self.assertEqual(letters, sorted(nucleotide_alphabet))
        path = os.path.join("Align", "ecoli.txt")
        frequencies = substitution_matrices.read(path)
        self.assertEqual(frequencies.alphabet, nucleotide_alphabet)
        self.assertEqual(frequencies.shape, (len(nucleotide_alphabet),))
        for letter in letters:
            self.assertAlmostEqual(frequencies[letter], counts[letter])
        with open(path) as handle:
            text = handle.read()
        self.assertEqual(frequencies.format("%d"), text)
        total = sum(frequencies)
        self.assertAlmostEqual(total, sum(counts.values()))
        frequencies /= total
        self.assertEqual(frequencies.alphabet, nucleotide_alphabet)
        self.assertAlmostEqual(frequencies["A"], 0.251621271076524)
        self.assertAlmostEqual(frequencies["C"], 0.228274967574578)
        self.assertAlmostEqual(frequencies["G"], 0.315175097276264)
        self.assertAlmostEqual(frequencies["T"], 0.204928664072632)
        counts = Counter()
        path = os.path.join("Align", "bsubtilis.fa")
        records = SeqIO.parse(path, "fasta")
        for record in records:
            for nucleotide in record.seq:
                counts[nucleotide] += 1
        letters = sorted(counts.keys())
        self.assertEqual(letters, sorted(nucleotide_alphabet))
        path = os.path.join("Align", "bsubtilis.txt")
        frequencies = substitution_matrices.read(path)
        self.assertEqual(frequencies.alphabet, nucleotide_alphabet)
        self.assertEqual(frequencies.shape, (len(nucleotide_alphabet),))
        for letter in letters:
            self.assertAlmostEqual(frequencies[letter], counts[letter])
        with open(path) as handle:
            text = handle.read()
        self.assertEqual(frequencies.format("%d"), text)
        total = sum(frequencies)
        self.assertAlmostEqual(total, sum(counts.values()))
        frequencies /= total
        self.assertEqual(frequencies.alphabet, nucleotide_alphabet)
        self.assertAlmostEqual(frequencies["A"], 0.2469453376205788)
        self.assertAlmostEqual(frequencies["C"], 0.2347266881028939)
        self.assertAlmostEqual(frequencies["G"], 0.3157556270096463)
        self.assertAlmostEqual(frequencies["T"], 0.2025723472668810)

    def test_protein_freq(self):
        """Test amino acid frequency calculations."""
        counts = Counter()
        path = os.path.join("Align", "cow.fa")
        records = SeqIO.parse(path, "fasta")
        for record in records:
            for aminoacid in record.seq:
                counts[aminoacid] += 1
        letters = sorted(counts.keys())
        self.assertEqual(letters, list(protein_alphabet))
        path = os.path.join("Align", "cow.txt")
        frequencies = substitution_matrices.read(path)
        self.assertEqual(frequencies.alphabet, protein_alphabet)
        self.assertEqual(frequencies.shape, (len(protein_alphabet),))
        for letter in letters:
            self.assertAlmostEqual(frequencies[letter], counts[letter])
        with open(path) as handle:
            text = handle.read()
        self.assertEqual(frequencies.format("%d"), text)
        total = sum(frequencies)
        self.assertAlmostEqual(total, sum(counts.values()))
        frequencies /= total
        self.assertEqual(frequencies.alphabet, protein_alphabet)
        self.assertAlmostEqual(frequencies["A"], 0.069711538)
        self.assertAlmostEqual(frequencies["C"], 0.025320513)
        self.assertAlmostEqual(frequencies["D"], 0.040785256)
        self.assertAlmostEqual(frequencies["E"], 0.058974359)
        self.assertAlmostEqual(frequencies["F"], 0.044951923)
        self.assertAlmostEqual(frequencies["G"], 0.058012821)
        self.assertAlmostEqual(frequencies["H"], 0.024278846)
        self.assertAlmostEqual(frequencies["I"], 0.056009615)
        self.assertAlmostEqual(frequencies["K"], 0.055448718)
        self.assertAlmostEqual(frequencies["L"], 0.117788462)
        self.assertAlmostEqual(frequencies["M"], 0.026442308)
        self.assertAlmostEqual(frequencies["N"], 0.035336538)
        self.assertAlmostEqual(frequencies["P"], 0.052003205)
        self.assertAlmostEqual(frequencies["Q"], 0.038621795)
        self.assertAlmostEqual(frequencies["R"], 0.050961538)
        self.assertAlmostEqual(frequencies["S"], 0.080368590)
        self.assertAlmostEqual(frequencies["T"], 0.054887821)
        self.assertAlmostEqual(frequencies["V"], 0.062500000)
        self.assertAlmostEqual(frequencies["W"], 0.015625000)
        self.assertAlmostEqual(frequencies["Y"], 0.031971154)
        counts = Counter()
        path = os.path.join("Align", "pig.fa")
        records = SeqIO.parse(path, "fasta")
        for record in records:
            for aminoacid in record.seq:
                counts[aminoacid] += 1
        letters = sorted(counts.keys())
        self.assertEqual(letters, list(protein_alphabet))
        path = os.path.join("Align", "pig.txt")
        frequencies = substitution_matrices.read(path)
        self.assertEqual(frequencies.alphabet, protein_alphabet)
        self.assertEqual(frequencies.shape, (len(protein_alphabet),))
        for letter in letters:
            self.assertAlmostEqual(frequencies[letter], counts[letter])
        with open(path) as handle:
            text = handle.read()
        self.assertEqual(frequencies.format("%d"), text)
        total = sum(frequencies)
        self.assertAlmostEqual(total, sum(counts.values()))
        frequencies /= total
        self.assertEqual(frequencies.alphabet, protein_alphabet)
        self.assertAlmostEqual(frequencies["A"], 0.070987178)
        self.assertAlmostEqual(frequencies["C"], 0.025490499)
        self.assertAlmostEqual(frequencies["D"], 0.041325506)
        self.assertAlmostEqual(frequencies["E"], 0.058550904)
        self.assertAlmostEqual(frequencies["F"], 0.046037386)
        self.assertAlmostEqual(frequencies["G"], 0.058164684)
        self.assertAlmostEqual(frequencies["H"], 0.022941449)
        self.assertAlmostEqual(frequencies["I"], 0.054534219)
        self.assertAlmostEqual(frequencies["K"], 0.054843195)
        self.assertAlmostEqual(frequencies["L"], 0.116020392)
        self.assertAlmostEqual(frequencies["M"], 0.026880890)
        self.assertAlmostEqual(frequencies["N"], 0.036613626)
        self.assertAlmostEqual(frequencies["P"], 0.051058242)
        self.assertAlmostEqual(frequencies["Q"], 0.040553067)
        self.assertAlmostEqual(frequencies["R"], 0.051135486)
        self.assertAlmostEqual(frequencies["S"], 0.079252279)
        self.assertAlmostEqual(frequencies["T"], 0.054070755)
        self.assertAlmostEqual(frequencies["V"], 0.064807663)
        self.assertAlmostEqual(frequencies["W"], 0.015217055)
        self.assertAlmostEqual(frequencies["Y"], 0.031515526)

    def test_pickling(self):
        """Test pickling a substitution matrix."""
        matrix = substitution_matrices.load("BLOSUM62")
        pickled = pickle.dumps(matrix)
        loaded = pickle.loads(pickled)
        self.assertEqual(matrix.alphabet, loaded.alphabet)
        for c1 in matrix.alphabet:
            for c2 in matrix.alphabet:
                self.assertAlmostEqual(matrix[c1, c2], loaded[c1, c2])


class TestScoringMatrices(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        from Bio import SeqIO
        from Bio.Align import PairwiseAligner

        observed = substitution_matrices.Array(alphabet=protein_alphabet, dims=2)
        aligner = PairwiseAligner()
        aligner.mode = "local"
        # By default, the affine gap penalties used by blastp are 11 for
        # existence of a gap and 1 for extending a gap. Using to Durbin"s
        # parametrization of affine gap scores, this is equivalent to an
        # gap score of -12 to open a gap, and -1 to extend an existing gap:
        aligner.open_gap_score = -12
        aligner.extend_gap_score = -1
        # Use +6/-1 match and mismatch scores as an approximation of the
        # BLOSUM62 matrix.
        aligner.match = 6
        aligner.mismatch = -1
        cow_path = "Align/cow.fa"
        pig_path = "Align/pig.fa"
        cow_records = SeqIO.parse(cow_path, "fasta")
        pig_records = SeqIO.parse(pig_path, "fasta")
        for cow_record, pig_record in zip(cow_records, pig_records):
            cow_sequence = cow_record.seq
            pig_sequence = pig_record.seq
            alignments = aligner.align(cow_sequence, pig_sequence)
            assert len(alignments) == 1
            alignment = alignments[0]
            cow_aligned, pig_aligned = alignment.aligned
            for cow_segment, pig_segment in zip(cow_aligned, pig_aligned):
                cow_start, cow_end = cow_segment
                pig_start, pig_end = pig_segment
                cow_subsequence = cow_sequence[cow_start:cow_end]
                pig_subsequence = pig_sequence[pig_start:pig_end]
                for c1, c2 in zip(cow_subsequence, pig_subsequence):
                    observed[c1, c2] += 1
        cls.observed = observed

    def test1_observed_frequencies(self):
        """Test calculating substitution frequencies."""
        observed = self.observed
        self.assertEqual(observed.alphabet, protein_alphabet)
        self.assertEqual(observed.shape, (20, 20))
        self.assertAlmostEqual(observed["A", "A"], 706)
        self.assertAlmostEqual(observed["A", "C"], 1)
        self.assertAlmostEqual(observed["A", "D"], 3)
        self.assertAlmostEqual(observed["A", "E"], 11)
        self.assertAlmostEqual(observed["A", "F"], 1)
        self.assertAlmostEqual(observed["A", "G"], 14)
        self.assertAlmostEqual(observed["A", "H"], 1)
        self.assertAlmostEqual(observed["A", "I"], 4)
        self.assertAlmostEqual(observed["A", "K"], 1)
        self.assertAlmostEqual(observed["A", "L"], 5)
        self.assertAlmostEqual(observed["A", "M"], 5)
        self.assertAlmostEqual(observed["A", "N"], 1)
        self.assertAlmostEqual(observed["A", "P"], 5)
        self.assertAlmostEqual(observed["A", "Q"], 0)
        self.assertAlmostEqual(observed["A", "R"], 1)
        self.assertAlmostEqual(observed["A", "S"], 22)
        self.assertAlmostEqual(observed["A", "T"], 37)
        self.assertAlmostEqual(observed["A", "V"], 35)
        self.assertAlmostEqual(observed["A", "W"], 0)
        self.assertAlmostEqual(observed["A", "Y"], 1)
        self.assertAlmostEqual(observed["C", "A"], 0)
        self.assertAlmostEqual(observed["C", "C"], 279)
        self.assertAlmostEqual(observed["C", "D"], 0)
        self.assertAlmostEqual(observed["C", "E"], 1)
        self.assertAlmostEqual(observed["C", "F"], 3)
        self.assertAlmostEqual(observed["C", "G"], 2)
        self.assertAlmostEqual(observed["C", "H"], 0)
        self.assertAlmostEqual(observed["C", "I"], 1)
        self.assertAlmostEqual(observed["C", "K"], 0)
        self.assertAlmostEqual(observed["C", "L"], 1)
        self.assertAlmostEqual(observed["C", "M"], 0)
        self.assertAlmostEqual(observed["C", "N"], 1)
        self.assertAlmostEqual(observed["C", "P"], 2)
        self.assertAlmostEqual(observed["C", "Q"], 0)
        self.assertAlmostEqual(observed["C", "R"], 6)
        self.assertAlmostEqual(observed["C", "S"], 6)
        self.assertAlmostEqual(observed["C", "T"], 0)
        self.assertAlmostEqual(observed["C", "V"], 1)
        self.assertAlmostEqual(observed["C", "W"], 1)
        self.assertAlmostEqual(observed["C", "Y"], 6)
        self.assertAlmostEqual(observed["D", "A"], 7)
        self.assertAlmostEqual(observed["D", "C"], 1)
        self.assertAlmostEqual(observed["D", "D"], 427)
        self.assertAlmostEqual(observed["D", "E"], 25)
        self.assertAlmostEqual(observed["D", "F"], 0)
        self.assertAlmostEqual(observed["D", "G"], 8)
        self.assertAlmostEqual(observed["D", "H"], 0)
        self.assertAlmostEqual(observed["D", "I"], 0)
        self.assertAlmostEqual(observed["D", "K"], 1)
        self.assertAlmostEqual(observed["D", "L"], 2)
        self.assertAlmostEqual(observed["D", "M"], 0)
        self.assertAlmostEqual(observed["D", "N"], 19)
        self.assertAlmostEqual(observed["D", "P"], 0)
        self.assertAlmostEqual(observed["D", "Q"], 0)
        self.assertAlmostEqual(observed["D", "R"], 3)
        self.assertAlmostEqual(observed["D", "S"], 3)
        self.assertAlmostEqual(observed["D", "T"], 1)
        self.assertAlmostEqual(observed["D", "V"], 1)
        self.assertAlmostEqual(observed["D", "W"], 1)
        self.assertAlmostEqual(observed["D", "Y"], 1)
        self.assertAlmostEqual(observed["E", "A"], 9)
        self.assertAlmostEqual(observed["E", "C"], 0)
        self.assertAlmostEqual(observed["E", "D"], 30)
        self.assertAlmostEqual(observed["E", "E"], 629)
        self.assertAlmostEqual(observed["E", "F"], 1)
        self.assertAlmostEqual(observed["E", "G"], 19)
        self.assertAlmostEqual(observed["E", "H"], 3)
        self.assertAlmostEqual(observed["E", "I"], 1)
        self.assertAlmostEqual(observed["E", "K"], 12)
        self.assertAlmostEqual(observed["E", "L"], 1)
        self.assertAlmostEqual(observed["E", "M"], 1)
        self.assertAlmostEqual(observed["E", "N"], 1)
        self.assertAlmostEqual(observed["E", "P"], 1)
        self.assertAlmostEqual(observed["E", "Q"], 12)
        self.assertAlmostEqual(observed["E", "R"], 5)
        self.assertAlmostEqual(observed["E", "S"], 3)
        self.assertAlmostEqual(observed["E", "T"], 1)
        self.assertAlmostEqual(observed["E", "V"], 1)
        self.assertAlmostEqual(observed["E", "W"], 0)
        self.assertAlmostEqual(observed["E", "Y"], 0)
        self.assertAlmostEqual(observed["F", "A"], 0)
        self.assertAlmostEqual(observed["F", "C"], 2)
        self.assertAlmostEqual(observed["F", "D"], 1)
        self.assertAlmostEqual(observed["F", "E"], 0)
        self.assertAlmostEqual(observed["F", "F"], 497)
        self.assertAlmostEqual(observed["F", "G"], 1)
        self.assertAlmostEqual(observed["F", "H"], 1)
        self.assertAlmostEqual(observed["F", "I"], 1)
        self.assertAlmostEqual(observed["F", "K"], 1)
        self.assertAlmostEqual(observed["F", "L"], 26)
        self.assertAlmostEqual(observed["F", "M"], 1)
        self.assertAlmostEqual(observed["F", "N"], 0)
        self.assertAlmostEqual(observed["F", "P"], 0)
        self.assertAlmostEqual(observed["F", "Q"], 0)
        self.assertAlmostEqual(observed["F", "R"], 0)
        self.assertAlmostEqual(observed["F", "S"], 6)
        self.assertAlmostEqual(observed["F", "T"], 3)
        self.assertAlmostEqual(observed["F", "V"], 4)
        self.assertAlmostEqual(observed["F", "W"], 1)
        self.assertAlmostEqual(observed["F", "Y"], 12)
        self.assertAlmostEqual(observed["G", "A"], 12)
        self.assertAlmostEqual(observed["G", "C"], 2)
        self.assertAlmostEqual(observed["G", "D"], 10)
        self.assertAlmostEqual(observed["G", "E"], 14)
        self.assertAlmostEqual(observed["G", "F"], 0)
        self.assertAlmostEqual(observed["G", "G"], 612)
        self.assertAlmostEqual(observed["G", "H"], 0)
        self.assertAlmostEqual(observed["G", "I"], 1)
        self.assertAlmostEqual(observed["G", "K"], 1)
        self.assertAlmostEqual(observed["G", "L"], 1)
        self.assertAlmostEqual(observed["G", "M"], 1)
        self.assertAlmostEqual(observed["G", "N"], 2)
        self.assertAlmostEqual(observed["G", "P"], 1)
        self.assertAlmostEqual(observed["G", "Q"], 1)
        self.assertAlmostEqual(observed["G", "R"], 13)
        self.assertAlmostEqual(observed["G", "S"], 22)
        self.assertAlmostEqual(observed["G", "T"], 1)
        self.assertAlmostEqual(observed["G", "V"], 8)
        self.assertAlmostEqual(observed["G", "W"], 2)
        self.assertAlmostEqual(observed["G", "Y"], 1)
        self.assertAlmostEqual(observed["H", "A"], 1)
        self.assertAlmostEqual(observed["H", "C"], 1)
        self.assertAlmostEqual(observed["H", "D"], 4)
        self.assertAlmostEqual(observed["H", "E"], 1)
        self.assertAlmostEqual(observed["H", "F"], 1)
        self.assertAlmostEqual(observed["H", "G"], 2)
        self.assertAlmostEqual(observed["H", "H"], 227)
        self.assertAlmostEqual(observed["H", "I"], 0)
        self.assertAlmostEqual(observed["H", "K"], 1)
        self.assertAlmostEqual(observed["H", "L"], 1)
        self.assertAlmostEqual(observed["H", "M"], 0)
        self.assertAlmostEqual(observed["H", "N"], 7)
        self.assertAlmostEqual(observed["H", "P"], 2)
        self.assertAlmostEqual(observed["H", "Q"], 14)
        self.assertAlmostEqual(observed["H", "R"], 20)
        self.assertAlmostEqual(observed["H", "S"], 3)
        self.assertAlmostEqual(observed["H", "T"], 0)
        self.assertAlmostEqual(observed["H", "V"], 1)
        self.assertAlmostEqual(observed["H", "W"], 0)
        self.assertAlmostEqual(observed["H", "Y"], 7)
        self.assertAlmostEqual(observed["I", "A"], 5)
        self.assertAlmostEqual(observed["I", "C"], 0)
        self.assertAlmostEqual(observed["I", "D"], 1)
        self.assertAlmostEqual(observed["I", "E"], 2)
        self.assertAlmostEqual(observed["I", "F"], 5)
        self.assertAlmostEqual(observed["I", "G"], 0)
        self.assertAlmostEqual(observed["I", "H"], 1)
        self.assertAlmostEqual(observed["I", "I"], 558)
        self.assertAlmostEqual(observed["I", "K"], 1)
        self.assertAlmostEqual(observed["I", "L"], 22)
        self.assertAlmostEqual(observed["I", "M"], 11)
        self.assertAlmostEqual(observed["I", "N"], 3)
        self.assertAlmostEqual(observed["I", "P"], 1)
        self.assertAlmostEqual(observed["I", "Q"], 0)
        self.assertAlmostEqual(observed["I", "R"], 1)
        self.assertAlmostEqual(observed["I", "S"], 2)
        self.assertAlmostEqual(observed["I", "T"], 18)
        self.assertAlmostEqual(observed["I", "V"], 61)
        self.assertAlmostEqual(observed["I", "W"], 0)
        self.assertAlmostEqual(observed["I", "Y"], 1)
        self.assertAlmostEqual(observed["K", "A"], 3)
        self.assertAlmostEqual(observed["K", "C"], 1)
        self.assertAlmostEqual(observed["K", "D"], 1)
        self.assertAlmostEqual(observed["K", "E"], 17)
        self.assertAlmostEqual(observed["K", "F"], 0)
        self.assertAlmostEqual(observed["K", "G"], 2)
        self.assertAlmostEqual(observed["K", "H"], 2)
        self.assertAlmostEqual(observed["K", "I"], 2)
        self.assertAlmostEqual(observed["K", "K"], 573)
        self.assertAlmostEqual(observed["K", "L"], 0)
        self.assertAlmostEqual(observed["K", "M"], 2)
        self.assertAlmostEqual(observed["K", "N"], 11)
        self.assertAlmostEqual(observed["K", "P"], 1)
        self.assertAlmostEqual(observed["K", "Q"], 13)
        self.assertAlmostEqual(observed["K", "R"], 46)
        self.assertAlmostEqual(observed["K", "S"], 0)
        self.assertAlmostEqual(observed["K", "T"], 9)
        self.assertAlmostEqual(observed["K", "V"], 1)
        self.assertAlmostEqual(observed["K", "W"], 0)
        self.assertAlmostEqual(observed["K", "Y"], 1)
        self.assertAlmostEqual(observed["L", "A"], 7)
        self.assertAlmostEqual(observed["L", "C"], 1)
        self.assertAlmostEqual(observed["L", "D"], 0)
        self.assertAlmostEqual(observed["L", "E"], 1)
        self.assertAlmostEqual(observed["L", "F"], 26)
        self.assertAlmostEqual(observed["L", "G"], 2)
        self.assertAlmostEqual(observed["L", "H"], 1)
        self.assertAlmostEqual(observed["L", "I"], 21)
        self.assertAlmostEqual(observed["L", "K"], 1)
        self.assertAlmostEqual(observed["L", "L"], 1300)
        self.assertAlmostEqual(observed["L", "M"], 19)
        self.assertAlmostEqual(observed["L", "N"], 1)
        self.assertAlmostEqual(observed["L", "P"], 17)
        self.assertAlmostEqual(observed["L", "Q"], 4)
        self.assertAlmostEqual(observed["L", "R"], 3)
        self.assertAlmostEqual(observed["L", "S"], 9)
        self.assertAlmostEqual(observed["L", "T"], 4)
        self.assertAlmostEqual(observed["L", "V"], 37)
        self.assertAlmostEqual(observed["L", "W"], 2)
        self.assertAlmostEqual(observed["L", "Y"], 0)
        self.assertAlmostEqual(observed["M", "A"], 0)
        self.assertAlmostEqual(observed["M", "C"], 1)
        self.assertAlmostEqual(observed["M", "D"], 1)
        self.assertAlmostEqual(observed["M", "E"], 0)
        self.assertAlmostEqual(observed["M", "F"], 1)
        self.assertAlmostEqual(observed["M", "G"], 2)
        self.assertAlmostEqual(observed["M", "H"], 1)
        self.assertAlmostEqual(observed["M", "I"], 14)
        self.assertAlmostEqual(observed["M", "K"], 3)
        self.assertAlmostEqual(observed["M", "L"], 18)
        self.assertAlmostEqual(observed["M", "M"], 263)
        self.assertAlmostEqual(observed["M", "N"], 0)
        self.assertAlmostEqual(observed["M", "P"], 1)
        self.assertAlmostEqual(observed["M", "Q"], 0)
        self.assertAlmostEqual(observed["M", "R"], 1)
        self.assertAlmostEqual(observed["M", "S"], 2)
        self.assertAlmostEqual(observed["M", "T"], 7)
        self.assertAlmostEqual(observed["M", "V"], 6)
        self.assertAlmostEqual(observed["M", "W"], 0)
        self.assertAlmostEqual(observed["M", "Y"], 1)
        self.assertAlmostEqual(observed["N", "A"], 2)
        self.assertAlmostEqual(observed["N", "C"], 0)
        self.assertAlmostEqual(observed["N", "D"], 21)
        self.assertAlmostEqual(observed["N", "E"], 1)
        self.assertAlmostEqual(observed["N", "F"], 2)
        self.assertAlmostEqual(observed["N", "G"], 5)
        self.assertAlmostEqual(observed["N", "H"], 4)
        self.assertAlmostEqual(observed["N", "I"], 2)
        self.assertAlmostEqual(observed["N", "K"], 8)
        self.assertAlmostEqual(observed["N", "L"], 2)
        self.assertAlmostEqual(observed["N", "M"], 1)
        self.assertAlmostEqual(observed["N", "N"], 360)
        self.assertAlmostEqual(observed["N", "P"], 0)
        self.assertAlmostEqual(observed["N", "Q"], 3)
        self.assertAlmostEqual(observed["N", "R"], 1)
        self.assertAlmostEqual(observed["N", "S"], 15)
        self.assertAlmostEqual(observed["N", "T"], 8)
        self.assertAlmostEqual(observed["N", "V"], 0)
        self.assertAlmostEqual(observed["N", "W"], 0)
        self.assertAlmostEqual(observed["N", "Y"], 2)
        self.assertAlmostEqual(observed["P", "A"], 14)
        self.assertAlmostEqual(observed["P", "C"], 0)
        self.assertAlmostEqual(observed["P", "D"], 1)
        self.assertAlmostEqual(observed["P", "E"], 0)
        self.assertAlmostEqual(observed["P", "F"], 1)
        self.assertAlmostEqual(observed["P", "G"], 0)
        self.assertAlmostEqual(observed["P", "H"], 5)
        self.assertAlmostEqual(observed["P", "I"], 0)
        self.assertAlmostEqual(observed["P", "K"], 0)
        self.assertAlmostEqual(observed["P", "L"], 16)
        self.assertAlmostEqual(observed["P", "M"], 0)
        self.assertAlmostEqual(observed["P", "N"], 1)
        self.assertAlmostEqual(observed["P", "P"], 551)
        self.assertAlmostEqual(observed["P", "Q"], 3)
        self.assertAlmostEqual(observed["P", "R"], 2)
        self.assertAlmostEqual(observed["P", "S"], 24)
        self.assertAlmostEqual(observed["P", "T"], 7)
        self.assertAlmostEqual(observed["P", "V"], 2)
        self.assertAlmostEqual(observed["P", "W"], 1)
        self.assertAlmostEqual(observed["P", "Y"], 0)
        self.assertAlmostEqual(observed["Q", "A"], 1)
        self.assertAlmostEqual(observed["Q", "C"], 1)
        self.assertAlmostEqual(observed["Q", "D"], 1)
        self.assertAlmostEqual(observed["Q", "E"], 10)
        self.assertAlmostEqual(observed["Q", "F"], 1)
        self.assertAlmostEqual(observed["Q", "G"], 0)
        self.assertAlmostEqual(observed["Q", "H"], 6)
        self.assertAlmostEqual(observed["Q", "I"], 1)
        self.assertAlmostEqual(observed["Q", "K"], 13)
        self.assertAlmostEqual(observed["Q", "L"], 5)
        self.assertAlmostEqual(observed["Q", "M"], 1)
        self.assertAlmostEqual(observed["Q", "N"], 2)
        self.assertAlmostEqual(observed["Q", "P"], 1)
        self.assertAlmostEqual(observed["Q", "Q"], 409)
        self.assertAlmostEqual(observed["Q", "R"], 18)
        self.assertAlmostEqual(observed["Q", "S"], 1)
        self.assertAlmostEqual(observed["Q", "T"], 0)
        self.assertAlmostEqual(observed["Q", "V"], 1)
        self.assertAlmostEqual(observed["Q", "W"], 0)
        self.assertAlmostEqual(observed["Q", "Y"], 0)
        self.assertAlmostEqual(observed["R", "A"], 3)
        self.assertAlmostEqual(observed["R", "C"], 3)
        self.assertAlmostEqual(observed["R", "D"], 0)
        self.assertAlmostEqual(observed["R", "E"], 2)
        self.assertAlmostEqual(observed["R", "F"], 1)
        self.assertAlmostEqual(observed["R", "G"], 13)
        self.assertAlmostEqual(observed["R", "H"], 6)
        self.assertAlmostEqual(observed["R", "I"], 0)
        self.assertAlmostEqual(observed["R", "K"], 40)
        self.assertAlmostEqual(observed["R", "L"], 5)
        self.assertAlmostEqual(observed["R", "M"], 2)
        self.assertAlmostEqual(observed["R", "N"], 4)
        self.assertAlmostEqual(observed["R", "P"], 5)
        self.assertAlmostEqual(observed["R", "Q"], 29)
        self.assertAlmostEqual(observed["R", "R"], 492)
        self.assertAlmostEqual(observed["R", "S"], 9)
        self.assertAlmostEqual(observed["R", "T"], 3)
        self.assertAlmostEqual(observed["R", "V"], 2)
        self.assertAlmostEqual(observed["R", "W"], 1)
        self.assertAlmostEqual(observed["R", "Y"], 0)
        self.assertAlmostEqual(observed["S", "A"], 34)
        self.assertAlmostEqual(observed["S", "C"], 3)
        self.assertAlmostEqual(observed["S", "D"], 3)
        self.assertAlmostEqual(observed["S", "E"], 3)
        self.assertAlmostEqual(observed["S", "F"], 9)
        self.assertAlmostEqual(observed["S", "G"], 18)
        self.assertAlmostEqual(observed["S", "H"], 2)
        self.assertAlmostEqual(observed["S", "I"], 4)
        self.assertAlmostEqual(observed["S", "K"], 4)
        self.assertAlmostEqual(observed["S", "L"], 3)
        self.assertAlmostEqual(observed["S", "M"], 0)
        self.assertAlmostEqual(observed["S", "N"], 25)
        self.assertAlmostEqual(observed["S", "P"], 19)
        self.assertAlmostEqual(observed["S", "Q"], 2)
        self.assertAlmostEqual(observed["S", "R"], 11)
        self.assertAlmostEqual(observed["S", "S"], 803)
        self.assertAlmostEqual(observed["S", "T"], 26)
        self.assertAlmostEqual(observed["S", "V"], 3)
        self.assertAlmostEqual(observed["S", "W"], 2)
        self.assertAlmostEqual(observed["S", "Y"], 6)
        self.assertAlmostEqual(observed["T", "A"], 43)
        self.assertAlmostEqual(observed["T", "C"], 1)
        self.assertAlmostEqual(observed["T", "D"], 4)
        self.assertAlmostEqual(observed["T", "E"], 1)
        self.assertAlmostEqual(observed["T", "F"], 0)
        self.assertAlmostEqual(observed["T", "G"], 2)
        self.assertAlmostEqual(observed["T", "H"], 1)
        self.assertAlmostEqual(observed["T", "I"], 18)
        self.assertAlmostEqual(observed["T", "K"], 4)
        self.assertAlmostEqual(observed["T", "L"], 4)
        self.assertAlmostEqual(observed["T", "M"], 16)
        self.assertAlmostEqual(observed["T", "N"], 8)
        self.assertAlmostEqual(observed["T", "P"], 9)
        self.assertAlmostEqual(observed["T", "Q"], 2)
        self.assertAlmostEqual(observed["T", "R"], 2)
        self.assertAlmostEqual(observed["T", "S"], 27)
        self.assertAlmostEqual(observed["T", "T"], 526)
        self.assertAlmostEqual(observed["T", "V"], 6)
        self.assertAlmostEqual(observed["T", "W"], 1)
        self.assertAlmostEqual(observed["T", "Y"], 1)
        self.assertAlmostEqual(observed["V", "A"], 25)
        self.assertAlmostEqual(observed["V", "C"], 1)
        self.assertAlmostEqual(observed["V", "D"], 3)
        self.assertAlmostEqual(observed["V", "E"], 2)
        self.assertAlmostEqual(observed["V", "F"], 6)
        self.assertAlmostEqual(observed["V", "G"], 9)
        self.assertAlmostEqual(observed["V", "H"], 0)
        self.assertAlmostEqual(observed["V", "I"], 48)
        self.assertAlmostEqual(observed["V", "K"], 1)
        self.assertAlmostEqual(observed["V", "L"], 21)
        self.assertAlmostEqual(observed["V", "M"], 8)
        self.assertAlmostEqual(observed["V", "N"], 1)
        self.assertAlmostEqual(observed["V", "P"], 2)
        self.assertAlmostEqual(observed["V", "Q"], 1)
        self.assertAlmostEqual(observed["V", "R"], 3)
        self.assertAlmostEqual(observed["V", "S"], 3)
        self.assertAlmostEqual(observed["V", "T"], 13)
        self.assertAlmostEqual(observed["V", "V"], 623)
        self.assertAlmostEqual(observed["V", "W"], 1)
        self.assertAlmostEqual(observed["V", "Y"], 0)
        self.assertAlmostEqual(observed["W", "A"], 2)
        self.assertAlmostEqual(observed["W", "C"], 1)
        self.assertAlmostEqual(observed["W", "D"], 0)
        self.assertAlmostEqual(observed["W", "E"], 1)
        self.assertAlmostEqual(observed["W", "F"], 0)
        self.assertAlmostEqual(observed["W", "G"], 4)
        self.assertAlmostEqual(observed["W", "H"], 1)
        self.assertAlmostEqual(observed["W", "I"], 1)
        self.assertAlmostEqual(observed["W", "K"], 1)
        self.assertAlmostEqual(observed["W", "L"], 2)
        self.assertAlmostEqual(observed["W", "M"], 1)
        self.assertAlmostEqual(observed["W", "N"], 1)
        self.assertAlmostEqual(observed["W", "P"], 0)
        self.assertAlmostEqual(observed["W", "Q"], 1)
        self.assertAlmostEqual(observed["W", "R"], 7)
        self.assertAlmostEqual(observed["W", "S"], 0)
        self.assertAlmostEqual(observed["W", "T"], 1)
        self.assertAlmostEqual(observed["W", "V"], 0)
        self.assertAlmostEqual(observed["W", "W"], 170)
        self.assertAlmostEqual(observed["W", "Y"], 0)
        self.assertAlmostEqual(observed["Y", "A"], 0)
        self.assertAlmostEqual(observed["Y", "C"], 4)
        self.assertAlmostEqual(observed["Y", "D"], 1)
        self.assertAlmostEqual(observed["Y", "E"], 1)
        self.assertAlmostEqual(observed["Y", "F"], 13)
        self.assertAlmostEqual(observed["Y", "G"], 0)
        self.assertAlmostEqual(observed["Y", "H"], 15)
        self.assertAlmostEqual(observed["Y", "I"], 0)
        self.assertAlmostEqual(observed["Y", "K"], 1)
        self.assertAlmostEqual(observed["Y", "L"], 2)
        self.assertAlmostEqual(observed["Y", "M"], 0)
        self.assertAlmostEqual(observed["Y", "N"], 0)
        self.assertAlmostEqual(observed["Y", "P"], 1)
        self.assertAlmostEqual(observed["Y", "Q"], 2)
        self.assertAlmostEqual(observed["Y", "R"], 1)
        self.assertAlmostEqual(observed["Y", "S"], 2)
        self.assertAlmostEqual(observed["Y", "T"], 0)
        self.assertAlmostEqual(observed["Y", "V"], 1)
        self.assertAlmostEqual(observed["Y", "W"], 1)
        self.assertAlmostEqual(observed["Y", "Y"], 352)

    def test2_observed_probabilities(self):
        """Test calculating substitution probabilities."""
        observed = self.observed
        # convert observed frequencies to probabilities
        total = observed.sum()
        observed[:, :] /= total
        self.assertEqual(observed.alphabet, protein_alphabet)
        self.assertEqual(observed.shape, (20, 20))
        self.assertAlmostEqual(observed["A", "A"], 0.057491857)
        self.assertAlmostEqual(observed["A", "C"], 0.000081433)
        self.assertAlmostEqual(observed["A", "D"], 0.000244300)
        self.assertAlmostEqual(observed["A", "E"], 0.000895765)
        self.assertAlmostEqual(observed["A", "F"], 0.000081433)
        self.assertAlmostEqual(observed["A", "G"], 0.001140065)
        self.assertAlmostEqual(observed["A", "H"], 0.000081433)
        self.assertAlmostEqual(observed["A", "I"], 0.000325733)
        self.assertAlmostEqual(observed["A", "K"], 0.000081433)
        self.assertAlmostEqual(observed["A", "L"], 0.000407166)
        self.assertAlmostEqual(observed["A", "M"], 0.000407166)
        self.assertAlmostEqual(observed["A", "N"], 0.000081433)
        self.assertAlmostEqual(observed["A", "P"], 0.000407166)
        self.assertAlmostEqual(observed["A", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["A", "R"], 0.000081433)
        self.assertAlmostEqual(observed["A", "S"], 0.001791531)
        self.assertAlmostEqual(observed["A", "T"], 0.003013029)
        self.assertAlmostEqual(observed["A", "V"], 0.002850163)
        self.assertAlmostEqual(observed["A", "W"], 0.000000000)
        self.assertAlmostEqual(observed["A", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["C", "A"], 0.000000000)
        self.assertAlmostEqual(observed["C", "C"], 0.022719870)
        self.assertAlmostEqual(observed["C", "D"], 0.000000000)
        self.assertAlmostEqual(observed["C", "E"], 0.000081433)
        self.assertAlmostEqual(observed["C", "F"], 0.000244300)
        self.assertAlmostEqual(observed["C", "G"], 0.000162866)
        self.assertAlmostEqual(observed["C", "H"], 0.000000000)
        self.assertAlmostEqual(observed["C", "I"], 0.000081433)
        self.assertAlmostEqual(observed["C", "K"], 0.000000000)
        self.assertAlmostEqual(observed["C", "L"], 0.000081433)
        self.assertAlmostEqual(observed["C", "M"], 0.000000000)
        self.assertAlmostEqual(observed["C", "N"], 0.000081433)
        self.assertAlmostEqual(observed["C", "P"], 0.000162866)
        self.assertAlmostEqual(observed["C", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["C", "R"], 0.000488599)
        self.assertAlmostEqual(observed["C", "S"], 0.000488599)
        self.assertAlmostEqual(observed["C", "T"], 0.000000000)
        self.assertAlmostEqual(observed["C", "V"], 0.000081433)
        self.assertAlmostEqual(observed["C", "W"], 0.000081433)
        self.assertAlmostEqual(observed["C", "Y"], 0.000488599)
        self.assertAlmostEqual(observed["D", "A"], 0.000570033)
        self.assertAlmostEqual(observed["D", "C"], 0.000081433)
        self.assertAlmostEqual(observed["D", "D"], 0.034771987)
        self.assertAlmostEqual(observed["D", "E"], 0.002035831)
        self.assertAlmostEqual(observed["D", "F"], 0.000000000)
        self.assertAlmostEqual(observed["D", "G"], 0.000651466)
        self.assertAlmostEqual(observed["D", "H"], 0.000000000)
        self.assertAlmostEqual(observed["D", "I"], 0.000000000)
        self.assertAlmostEqual(observed["D", "K"], 0.000081433)
        self.assertAlmostEqual(observed["D", "L"], 0.000162866)
        self.assertAlmostEqual(observed["D", "M"], 0.000000000)
        self.assertAlmostEqual(observed["D", "N"], 0.001547231)
        self.assertAlmostEqual(observed["D", "P"], 0.000000000)
        self.assertAlmostEqual(observed["D", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["D", "R"], 0.000244300)
        self.assertAlmostEqual(observed["D", "S"], 0.000244300)
        self.assertAlmostEqual(observed["D", "T"], 0.000081433)
        self.assertAlmostEqual(observed["D", "V"], 0.000081433)
        self.assertAlmostEqual(observed["D", "W"], 0.000081433)
        self.assertAlmostEqual(observed["D", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["E", "A"], 0.000732899)
        self.assertAlmostEqual(observed["E", "C"], 0.000000000)
        self.assertAlmostEqual(observed["E", "D"], 0.002442997)
        self.assertAlmostEqual(observed["E", "E"], 0.051221498)
        self.assertAlmostEqual(observed["E", "F"], 0.000081433)
        self.assertAlmostEqual(observed["E", "G"], 0.001547231)
        self.assertAlmostEqual(observed["E", "H"], 0.000244300)
        self.assertAlmostEqual(observed["E", "I"], 0.000081433)
        self.assertAlmostEqual(observed["E", "K"], 0.000977199)
        self.assertAlmostEqual(observed["E", "L"], 0.000081433)
        self.assertAlmostEqual(observed["E", "M"], 0.000081433)
        self.assertAlmostEqual(observed["E", "N"], 0.000081433)
        self.assertAlmostEqual(observed["E", "P"], 0.000081433)
        self.assertAlmostEqual(observed["E", "Q"], 0.000977199)
        self.assertAlmostEqual(observed["E", "R"], 0.000407166)
        self.assertAlmostEqual(observed["E", "S"], 0.000244300)
        self.assertAlmostEqual(observed["E", "T"], 0.000081433)
        self.assertAlmostEqual(observed["E", "V"], 0.000081433)
        self.assertAlmostEqual(observed["E", "W"], 0.000000000)
        self.assertAlmostEqual(observed["E", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["F", "A"], 0.000000000)
        self.assertAlmostEqual(observed["F", "C"], 0.000162866)
        self.assertAlmostEqual(observed["F", "D"], 0.000081433)
        self.assertAlmostEqual(observed["F", "E"], 0.000000000)
        self.assertAlmostEqual(observed["F", "F"], 0.040472313)
        self.assertAlmostEqual(observed["F", "G"], 0.000081433)
        self.assertAlmostEqual(observed["F", "H"], 0.000081433)
        self.assertAlmostEqual(observed["F", "I"], 0.000081433)
        self.assertAlmostEqual(observed["F", "K"], 0.000081433)
        self.assertAlmostEqual(observed["F", "L"], 0.002117264)
        self.assertAlmostEqual(observed["F", "M"], 0.000081433)
        self.assertAlmostEqual(observed["F", "N"], 0.000000000)
        self.assertAlmostEqual(observed["F", "P"], 0.000000000)
        self.assertAlmostEqual(observed["F", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["F", "R"], 0.000000000)
        self.assertAlmostEqual(observed["F", "S"], 0.000488599)
        self.assertAlmostEqual(observed["F", "T"], 0.000244300)
        self.assertAlmostEqual(observed["F", "V"], 0.000325733)
        self.assertAlmostEqual(observed["F", "W"], 0.000081433)
        self.assertAlmostEqual(observed["F", "Y"], 0.000977199)
        self.assertAlmostEqual(observed["G", "A"], 0.000977199)
        self.assertAlmostEqual(observed["G", "C"], 0.000162866)
        self.assertAlmostEqual(observed["G", "D"], 0.000814332)
        self.assertAlmostEqual(observed["G", "E"], 0.001140065)
        self.assertAlmostEqual(observed["G", "F"], 0.000000000)
        self.assertAlmostEqual(observed["G", "G"], 0.049837134)
        self.assertAlmostEqual(observed["G", "H"], 0.000000000)
        self.assertAlmostEqual(observed["G", "I"], 0.000081433)
        self.assertAlmostEqual(observed["G", "K"], 0.000081433)
        self.assertAlmostEqual(observed["G", "L"], 0.000081433)
        self.assertAlmostEqual(observed["G", "M"], 0.000081433)
        self.assertAlmostEqual(observed["G", "N"], 0.000162866)
        self.assertAlmostEqual(observed["G", "P"], 0.000081433)
        self.assertAlmostEqual(observed["G", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["G", "R"], 0.001058632)
        self.assertAlmostEqual(observed["G", "S"], 0.001791531)
        self.assertAlmostEqual(observed["G", "T"], 0.000081433)
        self.assertAlmostEqual(observed["G", "V"], 0.000651466)
        self.assertAlmostEqual(observed["G", "W"], 0.000162866)
        self.assertAlmostEqual(observed["G", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["H", "A"], 0.000081433)
        self.assertAlmostEqual(observed["H", "C"], 0.000081433)
        self.assertAlmostEqual(observed["H", "D"], 0.000325733)
        self.assertAlmostEqual(observed["H", "E"], 0.000081433)
        self.assertAlmostEqual(observed["H", "F"], 0.000081433)
        self.assertAlmostEqual(observed["H", "G"], 0.000162866)
        self.assertAlmostEqual(observed["H", "H"], 0.018485342)
        self.assertAlmostEqual(observed["H", "I"], 0.000000000)
        self.assertAlmostEqual(observed["H", "K"], 0.000081433)
        self.assertAlmostEqual(observed["H", "L"], 0.000081433)
        self.assertAlmostEqual(observed["H", "M"], 0.000000000)
        self.assertAlmostEqual(observed["H", "N"], 0.000570033)
        self.assertAlmostEqual(observed["H", "P"], 0.000162866)
        self.assertAlmostEqual(observed["H", "Q"], 0.001140065)
        self.assertAlmostEqual(observed["H", "R"], 0.001628664)
        self.assertAlmostEqual(observed["H", "S"], 0.000244300)
        self.assertAlmostEqual(observed["H", "T"], 0.000000000)
        self.assertAlmostEqual(observed["H", "V"], 0.000081433)
        self.assertAlmostEqual(observed["H", "W"], 0.000000000)
        self.assertAlmostEqual(observed["H", "Y"], 0.000570033)
        self.assertAlmostEqual(observed["I", "A"], 0.000407166)
        self.assertAlmostEqual(observed["I", "C"], 0.000000000)
        self.assertAlmostEqual(observed["I", "D"], 0.000081433)
        self.assertAlmostEqual(observed["I", "E"], 0.000162866)
        self.assertAlmostEqual(observed["I", "F"], 0.000407166)
        self.assertAlmostEqual(observed["I", "G"], 0.000000000)
        self.assertAlmostEqual(observed["I", "H"], 0.000081433)
        self.assertAlmostEqual(observed["I", "I"], 0.045439739)
        self.assertAlmostEqual(observed["I", "K"], 0.000081433)
        self.assertAlmostEqual(observed["I", "L"], 0.001791531)
        self.assertAlmostEqual(observed["I", "M"], 0.000895765)
        self.assertAlmostEqual(observed["I", "N"], 0.000244300)
        self.assertAlmostEqual(observed["I", "P"], 0.000081433)
        self.assertAlmostEqual(observed["I", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["I", "R"], 0.000081433)
        self.assertAlmostEqual(observed["I", "S"], 0.000162866)
        self.assertAlmostEqual(observed["I", "T"], 0.001465798)
        self.assertAlmostEqual(observed["I", "V"], 0.004967427)
        self.assertAlmostEqual(observed["I", "W"], 0.000000000)
        self.assertAlmostEqual(observed["I", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["K", "A"], 0.000244300)
        self.assertAlmostEqual(observed["K", "C"], 0.000081433)
        self.assertAlmostEqual(observed["K", "D"], 0.000081433)
        self.assertAlmostEqual(observed["K", "E"], 0.001384365)
        self.assertAlmostEqual(observed["K", "F"], 0.000000000)
        self.assertAlmostEqual(observed["K", "G"], 0.000162866)
        self.assertAlmostEqual(observed["K", "H"], 0.000162866)
        self.assertAlmostEqual(observed["K", "I"], 0.000162866)
        self.assertAlmostEqual(observed["K", "K"], 0.046661238)
        self.assertAlmostEqual(observed["K", "L"], 0.000000000)
        self.assertAlmostEqual(observed["K", "M"], 0.000162866)
        self.assertAlmostEqual(observed["K", "N"], 0.000895765)
        self.assertAlmostEqual(observed["K", "P"], 0.000081433)
        self.assertAlmostEqual(observed["K", "Q"], 0.001058632)
        self.assertAlmostEqual(observed["K", "R"], 0.003745928)
        self.assertAlmostEqual(observed["K", "S"], 0.000000000)
        self.assertAlmostEqual(observed["K", "T"], 0.000732899)
        self.assertAlmostEqual(observed["K", "V"], 0.000081433)
        self.assertAlmostEqual(observed["K", "W"], 0.000000000)
        self.assertAlmostEqual(observed["K", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["L", "A"], 0.000570033)
        self.assertAlmostEqual(observed["L", "C"], 0.000081433)
        self.assertAlmostEqual(observed["L", "D"], 0.000000000)
        self.assertAlmostEqual(observed["L", "E"], 0.000081433)
        self.assertAlmostEqual(observed["L", "F"], 0.002117264)
        self.assertAlmostEqual(observed["L", "G"], 0.000162866)
        self.assertAlmostEqual(observed["L", "H"], 0.000081433)
        self.assertAlmostEqual(observed["L", "I"], 0.001710098)
        self.assertAlmostEqual(observed["L", "K"], 0.000081433)
        self.assertAlmostEqual(observed["L", "L"], 0.105863192)
        self.assertAlmostEqual(observed["L", "M"], 0.001547231)
        self.assertAlmostEqual(observed["L", "N"], 0.000081433)
        self.assertAlmostEqual(observed["L", "P"], 0.001384365)
        self.assertAlmostEqual(observed["L", "Q"], 0.000325733)
        self.assertAlmostEqual(observed["L", "R"], 0.000244300)
        self.assertAlmostEqual(observed["L", "S"], 0.000732899)
        self.assertAlmostEqual(observed["L", "T"], 0.000325733)
        self.assertAlmostEqual(observed["L", "V"], 0.003013029)
        self.assertAlmostEqual(observed["L", "W"], 0.000162866)
        self.assertAlmostEqual(observed["L", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["M", "A"], 0.000000000)
        self.assertAlmostEqual(observed["M", "C"], 0.000081433)
        self.assertAlmostEqual(observed["M", "D"], 0.000081433)
        self.assertAlmostEqual(observed["M", "E"], 0.000000000)
        self.assertAlmostEqual(observed["M", "F"], 0.000081433)
        self.assertAlmostEqual(observed["M", "G"], 0.000162866)
        self.assertAlmostEqual(observed["M", "H"], 0.000081433)
        self.assertAlmostEqual(observed["M", "I"], 0.001140065)
        self.assertAlmostEqual(observed["M", "K"], 0.000244300)
        self.assertAlmostEqual(observed["M", "L"], 0.001465798)
        self.assertAlmostEqual(observed["M", "M"], 0.021416938)
        self.assertAlmostEqual(observed["M", "N"], 0.000000000)
        self.assertAlmostEqual(observed["M", "P"], 0.000081433)
        self.assertAlmostEqual(observed["M", "Q"], 0.000000000)
        self.assertAlmostEqual(observed["M", "R"], 0.000081433)
        self.assertAlmostEqual(observed["M", "S"], 0.000162866)
        self.assertAlmostEqual(observed["M", "T"], 0.000570033)
        self.assertAlmostEqual(observed["M", "V"], 0.000488599)
        self.assertAlmostEqual(observed["M", "W"], 0.000000000)
        self.assertAlmostEqual(observed["M", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["N", "A"], 0.000162866)
        self.assertAlmostEqual(observed["N", "C"], 0.000000000)
        self.assertAlmostEqual(observed["N", "D"], 0.001710098)
        self.assertAlmostEqual(observed["N", "E"], 0.000081433)
        self.assertAlmostEqual(observed["N", "F"], 0.000162866)
        self.assertAlmostEqual(observed["N", "G"], 0.000407166)
        self.assertAlmostEqual(observed["N", "H"], 0.000325733)
        self.assertAlmostEqual(observed["N", "I"], 0.000162866)
        self.assertAlmostEqual(observed["N", "K"], 0.000651466)
        self.assertAlmostEqual(observed["N", "L"], 0.000162866)
        self.assertAlmostEqual(observed["N", "M"], 0.000081433)
        self.assertAlmostEqual(observed["N", "N"], 0.029315961)
        self.assertAlmostEqual(observed["N", "P"], 0.000000000)
        self.assertAlmostEqual(observed["N", "Q"], 0.000244300)
        self.assertAlmostEqual(observed["N", "R"], 0.000081433)
        self.assertAlmostEqual(observed["N", "S"], 0.001221498)
        self.assertAlmostEqual(observed["N", "T"], 0.000651466)
        self.assertAlmostEqual(observed["N", "V"], 0.000000000)
        self.assertAlmostEqual(observed["N", "W"], 0.000000000)
        self.assertAlmostEqual(observed["N", "Y"], 0.000162866)
        self.assertAlmostEqual(observed["P", "A"], 0.001140065)
        self.assertAlmostEqual(observed["P", "C"], 0.000000000)
        self.assertAlmostEqual(observed["P", "D"], 0.000081433)
        self.assertAlmostEqual(observed["P", "E"], 0.000000000)
        self.assertAlmostEqual(observed["P", "F"], 0.000081433)
        self.assertAlmostEqual(observed["P", "G"], 0.000000000)
        self.assertAlmostEqual(observed["P", "H"], 0.000407166)
        self.assertAlmostEqual(observed["P", "I"], 0.000000000)
        self.assertAlmostEqual(observed["P", "K"], 0.000000000)
        self.assertAlmostEqual(observed["P", "L"], 0.001302932)
        self.assertAlmostEqual(observed["P", "M"], 0.000000000)
        self.assertAlmostEqual(observed["P", "N"], 0.000081433)
        self.assertAlmostEqual(observed["P", "P"], 0.044869707)
        self.assertAlmostEqual(observed["P", "Q"], 0.000244300)
        self.assertAlmostEqual(observed["P", "R"], 0.000162866)
        self.assertAlmostEqual(observed["P", "S"], 0.001954397)
        self.assertAlmostEqual(observed["P", "T"], 0.000570033)
        self.assertAlmostEqual(observed["P", "V"], 0.000162866)
        self.assertAlmostEqual(observed["P", "W"], 0.000081433)
        self.assertAlmostEqual(observed["P", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["Q", "A"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "C"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "D"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "E"], 0.000814332)
        self.assertAlmostEqual(observed["Q", "F"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "G"], 0.000000000)
        self.assertAlmostEqual(observed["Q", "H"], 0.000488599)
        self.assertAlmostEqual(observed["Q", "I"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "K"], 0.001058632)
        self.assertAlmostEqual(observed["Q", "L"], 0.000407166)
        self.assertAlmostEqual(observed["Q", "M"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "N"], 0.000162866)
        self.assertAlmostEqual(observed["Q", "P"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "Q"], 0.033306189)
        self.assertAlmostEqual(observed["Q", "R"], 0.001465798)
        self.assertAlmostEqual(observed["Q", "S"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "T"], 0.000000000)
        self.assertAlmostEqual(observed["Q", "V"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "W"], 0.000000000)
        self.assertAlmostEqual(observed["Q", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["R", "A"], 0.000244300)
        self.assertAlmostEqual(observed["R", "C"], 0.000244300)
        self.assertAlmostEqual(observed["R", "D"], 0.000000000)
        self.assertAlmostEqual(observed["R", "E"], 0.000162866)
        self.assertAlmostEqual(observed["R", "F"], 0.000081433)
        self.assertAlmostEqual(observed["R", "G"], 0.001058632)
        self.assertAlmostEqual(observed["R", "H"], 0.000488599)
        self.assertAlmostEqual(observed["R", "I"], 0.000000000)
        self.assertAlmostEqual(observed["R", "K"], 0.003257329)
        self.assertAlmostEqual(observed["R", "L"], 0.000407166)
        self.assertAlmostEqual(observed["R", "M"], 0.000162866)
        self.assertAlmostEqual(observed["R", "N"], 0.000325733)
        self.assertAlmostEqual(observed["R", "P"], 0.000407166)
        self.assertAlmostEqual(observed["R", "Q"], 0.002361564)
        self.assertAlmostEqual(observed["R", "R"], 0.040065147)
        self.assertAlmostEqual(observed["R", "S"], 0.000732899)
        self.assertAlmostEqual(observed["R", "T"], 0.000244300)
        self.assertAlmostEqual(observed["R", "V"], 0.000162866)
        self.assertAlmostEqual(observed["R", "W"], 0.000081433)
        self.assertAlmostEqual(observed["R", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["S", "A"], 0.002768730)
        self.assertAlmostEqual(observed["S", "C"], 0.000244300)
        self.assertAlmostEqual(observed["S", "D"], 0.000244300)
        self.assertAlmostEqual(observed["S", "E"], 0.000244300)
        self.assertAlmostEqual(observed["S", "F"], 0.000732899)
        self.assertAlmostEqual(observed["S", "G"], 0.001465798)
        self.assertAlmostEqual(observed["S", "H"], 0.000162866)
        self.assertAlmostEqual(observed["S", "I"], 0.000325733)
        self.assertAlmostEqual(observed["S", "K"], 0.000325733)
        self.assertAlmostEqual(observed["S", "L"], 0.000244300)
        self.assertAlmostEqual(observed["S", "M"], 0.000000000)
        self.assertAlmostEqual(observed["S", "N"], 0.002035831)
        self.assertAlmostEqual(observed["S", "P"], 0.001547231)
        self.assertAlmostEqual(observed["S", "Q"], 0.000162866)
        self.assertAlmostEqual(observed["S", "R"], 0.000895765)
        self.assertAlmostEqual(observed["S", "S"], 0.065390879)
        self.assertAlmostEqual(observed["S", "T"], 0.002117264)
        self.assertAlmostEqual(observed["S", "V"], 0.000244300)
        self.assertAlmostEqual(observed["S", "W"], 0.000162866)
        self.assertAlmostEqual(observed["S", "Y"], 0.000488599)
        self.assertAlmostEqual(observed["T", "A"], 0.003501629)
        self.assertAlmostEqual(observed["T", "C"], 0.000081433)
        self.assertAlmostEqual(observed["T", "D"], 0.000325733)
        self.assertAlmostEqual(observed["T", "E"], 0.000081433)
        self.assertAlmostEqual(observed["T", "F"], 0.000000000)
        self.assertAlmostEqual(observed["T", "G"], 0.000162866)
        self.assertAlmostEqual(observed["T", "H"], 0.000081433)
        self.assertAlmostEqual(observed["T", "I"], 0.001465798)
        self.assertAlmostEqual(observed["T", "K"], 0.000325733)
        self.assertAlmostEqual(observed["T", "L"], 0.000325733)
        self.assertAlmostEqual(observed["T", "M"], 0.001302932)
        self.assertAlmostEqual(observed["T", "N"], 0.000651466)
        self.assertAlmostEqual(observed["T", "P"], 0.000732899)
        self.assertAlmostEqual(observed["T", "Q"], 0.000162866)
        self.assertAlmostEqual(observed["T", "R"], 0.000162866)
        self.assertAlmostEqual(observed["T", "S"], 0.002198697)
        self.assertAlmostEqual(observed["T", "T"], 0.042833876)
        self.assertAlmostEqual(observed["T", "V"], 0.000488599)
        self.assertAlmostEqual(observed["T", "W"], 0.000081433)
        self.assertAlmostEqual(observed["T", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["V", "A"], 0.002035831)
        self.assertAlmostEqual(observed["V", "C"], 0.000081433)
        self.assertAlmostEqual(observed["V", "D"], 0.000244300)
        self.assertAlmostEqual(observed["V", "E"], 0.000162866)
        self.assertAlmostEqual(observed["V", "F"], 0.000488599)
        self.assertAlmostEqual(observed["V", "G"], 0.000732899)
        self.assertAlmostEqual(observed["V", "H"], 0.000000000)
        self.assertAlmostEqual(observed["V", "I"], 0.003908795)
        self.assertAlmostEqual(observed["V", "K"], 0.000081433)
        self.assertAlmostEqual(observed["V", "L"], 0.001710098)
        self.assertAlmostEqual(observed["V", "M"], 0.000651466)
        self.assertAlmostEqual(observed["V", "N"], 0.000081433)
        self.assertAlmostEqual(observed["V", "P"], 0.000162866)
        self.assertAlmostEqual(observed["V", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["V", "R"], 0.000244300)
        self.assertAlmostEqual(observed["V", "S"], 0.000244300)
        self.assertAlmostEqual(observed["V", "T"], 0.001058632)
        self.assertAlmostEqual(observed["V", "V"], 0.050732899)
        self.assertAlmostEqual(observed["V", "W"], 0.000081433)
        self.assertAlmostEqual(observed["V", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["W", "A"], 0.000162866)
        self.assertAlmostEqual(observed["W", "C"], 0.000081433)
        self.assertAlmostEqual(observed["W", "D"], 0.000000000)
        self.assertAlmostEqual(observed["W", "E"], 0.000081433)
        self.assertAlmostEqual(observed["W", "F"], 0.000000000)
        self.assertAlmostEqual(observed["W", "G"], 0.000325733)
        self.assertAlmostEqual(observed["W", "H"], 0.000081433)
        self.assertAlmostEqual(observed["W", "I"], 0.000081433)
        self.assertAlmostEqual(observed["W", "K"], 0.000081433)
        self.assertAlmostEqual(observed["W", "L"], 0.000162866)
        self.assertAlmostEqual(observed["W", "M"], 0.000081433)
        self.assertAlmostEqual(observed["W", "N"], 0.000081433)
        self.assertAlmostEqual(observed["W", "P"], 0.000000000)
        self.assertAlmostEqual(observed["W", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["W", "R"], 0.000570033)
        self.assertAlmostEqual(observed["W", "S"], 0.000000000)
        self.assertAlmostEqual(observed["W", "T"], 0.000081433)
        self.assertAlmostEqual(observed["W", "V"], 0.000000000)
        self.assertAlmostEqual(observed["W", "W"], 0.013843648)
        self.assertAlmostEqual(observed["W", "Y"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "A"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "C"], 0.000325733)
        self.assertAlmostEqual(observed["Y", "D"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "E"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "F"], 0.001058632)
        self.assertAlmostEqual(observed["Y", "G"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "H"], 0.001221498)
        self.assertAlmostEqual(observed["Y", "I"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "K"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "L"], 0.000162866)
        self.assertAlmostEqual(observed["Y", "M"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "N"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "P"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "Q"], 0.000162866)
        self.assertAlmostEqual(observed["Y", "R"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "S"], 0.000162866)
        self.assertAlmostEqual(observed["Y", "T"], 0.000000000)
        self.assertAlmostEqual(observed["Y", "V"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "W"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "Y"], 0.028664495)

    def test3_observed_symmetric_probabilities(self):
        """Test symmetrizing substitution probabilities."""
        observed = self.observed
        # make a symmetric matrix
        observed[:, :] = 0.5 * (observed + observed.transpose())
        self.assertEqual(observed.alphabet, protein_alphabet)
        self.assertEqual(observed.shape, (20, 20))
        self.assertAlmostEqual(observed["A", "A"], 0.057491857)
        self.assertAlmostEqual(observed["A", "C"], 0.000040717)
        self.assertAlmostEqual(observed["A", "D"], 0.000407166)
        self.assertAlmostEqual(observed["A", "E"], 0.000814332)
        self.assertAlmostEqual(observed["A", "F"], 0.000040717)
        self.assertAlmostEqual(observed["A", "G"], 0.001058632)
        self.assertAlmostEqual(observed["A", "H"], 0.000081433)
        self.assertAlmostEqual(observed["A", "I"], 0.000366450)
        self.assertAlmostEqual(observed["A", "K"], 0.000162866)
        self.assertAlmostEqual(observed["A", "L"], 0.000488599)
        self.assertAlmostEqual(observed["A", "M"], 0.000203583)
        self.assertAlmostEqual(observed["A", "N"], 0.000122150)
        self.assertAlmostEqual(observed["A", "P"], 0.000773616)
        self.assertAlmostEqual(observed["A", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["A", "R"], 0.000162866)
        self.assertAlmostEqual(observed["A", "S"], 0.002280130)
        self.assertAlmostEqual(observed["A", "T"], 0.003257329)
        self.assertAlmostEqual(observed["A", "V"], 0.002442997)
        self.assertAlmostEqual(observed["A", "W"], 0.000081433)
        self.assertAlmostEqual(observed["A", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["C", "A"], 0.000040717)
        self.assertAlmostEqual(observed["C", "C"], 0.022719870)
        self.assertAlmostEqual(observed["C", "D"], 0.000040717)
        self.assertAlmostEqual(observed["C", "E"], 0.000040717)
        self.assertAlmostEqual(observed["C", "F"], 0.000203583)
        self.assertAlmostEqual(observed["C", "G"], 0.000162866)
        self.assertAlmostEqual(observed["C", "H"], 0.000040717)
        self.assertAlmostEqual(observed["C", "I"], 0.000040717)
        self.assertAlmostEqual(observed["C", "K"], 0.000040717)
        self.assertAlmostEqual(observed["C", "L"], 0.000081433)
        self.assertAlmostEqual(observed["C", "M"], 0.000040717)
        self.assertAlmostEqual(observed["C", "N"], 0.000040717)
        self.assertAlmostEqual(observed["C", "P"], 0.000081433)
        self.assertAlmostEqual(observed["C", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["C", "R"], 0.000366450)
        self.assertAlmostEqual(observed["C", "S"], 0.000366450)
        self.assertAlmostEqual(observed["C", "T"], 0.000040717)
        self.assertAlmostEqual(observed["C", "V"], 0.000081433)
        self.assertAlmostEqual(observed["C", "W"], 0.000081433)
        self.assertAlmostEqual(observed["C", "Y"], 0.000407166)
        self.assertAlmostEqual(observed["D", "A"], 0.000407166)
        self.assertAlmostEqual(observed["D", "C"], 0.000040717)
        self.assertAlmostEqual(observed["D", "D"], 0.034771987)
        self.assertAlmostEqual(observed["D", "E"], 0.002239414)
        self.assertAlmostEqual(observed["D", "F"], 0.000040717)
        self.assertAlmostEqual(observed["D", "G"], 0.000732899)
        self.assertAlmostEqual(observed["D", "H"], 0.000162866)
        self.assertAlmostEqual(observed["D", "I"], 0.000040717)
        self.assertAlmostEqual(observed["D", "K"], 0.000081433)
        self.assertAlmostEqual(observed["D", "L"], 0.000081433)
        self.assertAlmostEqual(observed["D", "M"], 0.000040717)
        self.assertAlmostEqual(observed["D", "N"], 0.001628664)
        self.assertAlmostEqual(observed["D", "P"], 0.000040717)
        self.assertAlmostEqual(observed["D", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["D", "R"], 0.000122150)
        self.assertAlmostEqual(observed["D", "S"], 0.000244300)
        self.assertAlmostEqual(observed["D", "T"], 0.000203583)
        self.assertAlmostEqual(observed["D", "V"], 0.000162866)
        self.assertAlmostEqual(observed["D", "W"], 0.000040717)
        self.assertAlmostEqual(observed["D", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["E", "A"], 0.000814332)
        self.assertAlmostEqual(observed["E", "C"], 0.000040717)
        self.assertAlmostEqual(observed["E", "D"], 0.002239414)
        self.assertAlmostEqual(observed["E", "E"], 0.051221498)
        self.assertAlmostEqual(observed["E", "F"], 0.000040717)
        self.assertAlmostEqual(observed["E", "G"], 0.001343648)
        self.assertAlmostEqual(observed["E", "H"], 0.000162866)
        self.assertAlmostEqual(observed["E", "I"], 0.000122150)
        self.assertAlmostEqual(observed["E", "K"], 0.001180782)
        self.assertAlmostEqual(observed["E", "L"], 0.000081433)
        self.assertAlmostEqual(observed["E", "M"], 0.000040717)
        self.assertAlmostEqual(observed["E", "N"], 0.000081433)
        self.assertAlmostEqual(observed["E", "P"], 0.000040717)
        self.assertAlmostEqual(observed["E", "Q"], 0.000895765)
        self.assertAlmostEqual(observed["E", "R"], 0.000285016)
        self.assertAlmostEqual(observed["E", "S"], 0.000244300)
        self.assertAlmostEqual(observed["E", "T"], 0.000081433)
        self.assertAlmostEqual(observed["E", "V"], 0.000122150)
        self.assertAlmostEqual(observed["E", "W"], 0.000040717)
        self.assertAlmostEqual(observed["E", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["F", "A"], 0.000040717)
        self.assertAlmostEqual(observed["F", "C"], 0.000203583)
        self.assertAlmostEqual(observed["F", "D"], 0.000040717)
        self.assertAlmostEqual(observed["F", "E"], 0.000040717)
        self.assertAlmostEqual(observed["F", "F"], 0.040472313)
        self.assertAlmostEqual(observed["F", "G"], 0.000040717)
        self.assertAlmostEqual(observed["F", "H"], 0.000081433)
        self.assertAlmostEqual(observed["F", "I"], 0.000244300)
        self.assertAlmostEqual(observed["F", "K"], 0.000040717)
        self.assertAlmostEqual(observed["F", "L"], 0.002117264)
        self.assertAlmostEqual(observed["F", "M"], 0.000081433)
        self.assertAlmostEqual(observed["F", "N"], 0.000081433)
        self.assertAlmostEqual(observed["F", "P"], 0.000040717)
        self.assertAlmostEqual(observed["F", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["F", "R"], 0.000040717)
        self.assertAlmostEqual(observed["F", "S"], 0.000610749)
        self.assertAlmostEqual(observed["F", "T"], 0.000122150)
        self.assertAlmostEqual(observed["F", "V"], 0.000407166)
        self.assertAlmostEqual(observed["F", "W"], 0.000040717)
        self.assertAlmostEqual(observed["F", "Y"], 0.001017915)
        self.assertAlmostEqual(observed["G", "A"], 0.001058632)
        self.assertAlmostEqual(observed["G", "C"], 0.000162866)
        self.assertAlmostEqual(observed["G", "D"], 0.000732899)
        self.assertAlmostEqual(observed["G", "E"], 0.001343648)
        self.assertAlmostEqual(observed["G", "F"], 0.000040717)
        self.assertAlmostEqual(observed["G", "G"], 0.049837134)
        self.assertAlmostEqual(observed["G", "H"], 0.000081433)
        self.assertAlmostEqual(observed["G", "I"], 0.000040717)
        self.assertAlmostEqual(observed["G", "K"], 0.000122150)
        self.assertAlmostEqual(observed["G", "L"], 0.000122150)
        self.assertAlmostEqual(observed["G", "M"], 0.000122150)
        self.assertAlmostEqual(observed["G", "N"], 0.000285016)
        self.assertAlmostEqual(observed["G", "P"], 0.000040717)
        self.assertAlmostEqual(observed["G", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["G", "R"], 0.001058632)
        self.assertAlmostEqual(observed["G", "S"], 0.001628664)
        self.assertAlmostEqual(observed["G", "T"], 0.000122150)
        self.assertAlmostEqual(observed["G", "V"], 0.000692182)
        self.assertAlmostEqual(observed["G", "W"], 0.000244300)
        self.assertAlmostEqual(observed["G", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["H", "A"], 0.000081433)
        self.assertAlmostEqual(observed["H", "C"], 0.000040717)
        self.assertAlmostEqual(observed["H", "D"], 0.000162866)
        self.assertAlmostEqual(observed["H", "E"], 0.000162866)
        self.assertAlmostEqual(observed["H", "F"], 0.000081433)
        self.assertAlmostEqual(observed["H", "G"], 0.000081433)
        self.assertAlmostEqual(observed["H", "H"], 0.018485342)
        self.assertAlmostEqual(observed["H", "I"], 0.000040717)
        self.assertAlmostEqual(observed["H", "K"], 0.000122150)
        self.assertAlmostEqual(observed["H", "L"], 0.000081433)
        self.assertAlmostEqual(observed["H", "M"], 0.000040717)
        self.assertAlmostEqual(observed["H", "N"], 0.000447883)
        self.assertAlmostEqual(observed["H", "P"], 0.000285016)
        self.assertAlmostEqual(observed["H", "Q"], 0.000814332)
        self.assertAlmostEqual(observed["H", "R"], 0.001058632)
        self.assertAlmostEqual(observed["H", "S"], 0.000203583)
        self.assertAlmostEqual(observed["H", "T"], 0.000040717)
        self.assertAlmostEqual(observed["H", "V"], 0.000040717)
        self.assertAlmostEqual(observed["H", "W"], 0.000040717)
        self.assertAlmostEqual(observed["H", "Y"], 0.000895765)
        self.assertAlmostEqual(observed["I", "A"], 0.000366450)
        self.assertAlmostEqual(observed["I", "C"], 0.000040717)
        self.assertAlmostEqual(observed["I", "D"], 0.000040717)
        self.assertAlmostEqual(observed["I", "E"], 0.000122150)
        self.assertAlmostEqual(observed["I", "F"], 0.000244300)
        self.assertAlmostEqual(observed["I", "G"], 0.000040717)
        self.assertAlmostEqual(observed["I", "H"], 0.000040717)
        self.assertAlmostEqual(observed["I", "I"], 0.045439739)
        self.assertAlmostEqual(observed["I", "K"], 0.000122150)
        self.assertAlmostEqual(observed["I", "L"], 0.001750814)
        self.assertAlmostEqual(observed["I", "M"], 0.001017915)
        self.assertAlmostEqual(observed["I", "N"], 0.000203583)
        self.assertAlmostEqual(observed["I", "P"], 0.000040717)
        self.assertAlmostEqual(observed["I", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["I", "R"], 0.000040717)
        self.assertAlmostEqual(observed["I", "S"], 0.000244300)
        self.assertAlmostEqual(observed["I", "T"], 0.001465798)
        self.assertAlmostEqual(observed["I", "V"], 0.004438111)
        self.assertAlmostEqual(observed["I", "W"], 0.000040717)
        self.assertAlmostEqual(observed["I", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["K", "A"], 0.000162866)
        self.assertAlmostEqual(observed["K", "C"], 0.000040717)
        self.assertAlmostEqual(observed["K", "D"], 0.000081433)
        self.assertAlmostEqual(observed["K", "E"], 0.001180782)
        self.assertAlmostEqual(observed["K", "F"], 0.000040717)
        self.assertAlmostEqual(observed["K", "G"], 0.000122150)
        self.assertAlmostEqual(observed["K", "H"], 0.000122150)
        self.assertAlmostEqual(observed["K", "I"], 0.000122150)
        self.assertAlmostEqual(observed["K", "K"], 0.046661238)
        self.assertAlmostEqual(observed["K", "L"], 0.000040717)
        self.assertAlmostEqual(observed["K", "M"], 0.000203583)
        self.assertAlmostEqual(observed["K", "N"], 0.000773616)
        self.assertAlmostEqual(observed["K", "P"], 0.000040717)
        self.assertAlmostEqual(observed["K", "Q"], 0.001058632)
        self.assertAlmostEqual(observed["K", "R"], 0.003501629)
        self.assertAlmostEqual(observed["K", "S"], 0.000162866)
        self.assertAlmostEqual(observed["K", "T"], 0.000529316)
        self.assertAlmostEqual(observed["K", "V"], 0.000081433)
        self.assertAlmostEqual(observed["K", "W"], 0.000040717)
        self.assertAlmostEqual(observed["K", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["L", "A"], 0.000488599)
        self.assertAlmostEqual(observed["L", "C"], 0.000081433)
        self.assertAlmostEqual(observed["L", "D"], 0.000081433)
        self.assertAlmostEqual(observed["L", "E"], 0.000081433)
        self.assertAlmostEqual(observed["L", "F"], 0.002117264)
        self.assertAlmostEqual(observed["L", "G"], 0.000122150)
        self.assertAlmostEqual(observed["L", "H"], 0.000081433)
        self.assertAlmostEqual(observed["L", "I"], 0.001750814)
        self.assertAlmostEqual(observed["L", "K"], 0.000040717)
        self.assertAlmostEqual(observed["L", "L"], 0.105863192)
        self.assertAlmostEqual(observed["L", "M"], 0.001506515)
        self.assertAlmostEqual(observed["L", "N"], 0.000122150)
        self.assertAlmostEqual(observed["L", "P"], 0.001343648)
        self.assertAlmostEqual(observed["L", "Q"], 0.000366450)
        self.assertAlmostEqual(observed["L", "R"], 0.000325733)
        self.assertAlmostEqual(observed["L", "S"], 0.000488599)
        self.assertAlmostEqual(observed["L", "T"], 0.000325733)
        self.assertAlmostEqual(observed["L", "V"], 0.002361564)
        self.assertAlmostEqual(observed["L", "W"], 0.000162866)
        self.assertAlmostEqual(observed["L", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["M", "A"], 0.000203583)
        self.assertAlmostEqual(observed["M", "C"], 0.000040717)
        self.assertAlmostEqual(observed["M", "D"], 0.000040717)
        self.assertAlmostEqual(observed["M", "E"], 0.000040717)
        self.assertAlmostEqual(observed["M", "F"], 0.000081433)
        self.assertAlmostEqual(observed["M", "G"], 0.000122150)
        self.assertAlmostEqual(observed["M", "H"], 0.000040717)
        self.assertAlmostEqual(observed["M", "I"], 0.001017915)
        self.assertAlmostEqual(observed["M", "K"], 0.000203583)
        self.assertAlmostEqual(observed["M", "L"], 0.001506515)
        self.assertAlmostEqual(observed["M", "M"], 0.021416938)
        self.assertAlmostEqual(observed["M", "N"], 0.000040717)
        self.assertAlmostEqual(observed["M", "P"], 0.000040717)
        self.assertAlmostEqual(observed["M", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["M", "R"], 0.000122150)
        self.assertAlmostEqual(observed["M", "S"], 0.000081433)
        self.assertAlmostEqual(observed["M", "T"], 0.000936482)
        self.assertAlmostEqual(observed["M", "V"], 0.000570033)
        self.assertAlmostEqual(observed["M", "W"], 0.000040717)
        self.assertAlmostEqual(observed["M", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["N", "A"], 0.000122150)
        self.assertAlmostEqual(observed["N", "C"], 0.000040717)
        self.assertAlmostEqual(observed["N", "D"], 0.001628664)
        self.assertAlmostEqual(observed["N", "E"], 0.000081433)
        self.assertAlmostEqual(observed["N", "F"], 0.000081433)
        self.assertAlmostEqual(observed["N", "G"], 0.000285016)
        self.assertAlmostEqual(observed["N", "H"], 0.000447883)
        self.assertAlmostEqual(observed["N", "I"], 0.000203583)
        self.assertAlmostEqual(observed["N", "K"], 0.000773616)
        self.assertAlmostEqual(observed["N", "L"], 0.000122150)
        self.assertAlmostEqual(observed["N", "M"], 0.000040717)
        self.assertAlmostEqual(observed["N", "N"], 0.029315961)
        self.assertAlmostEqual(observed["N", "P"], 0.000040717)
        self.assertAlmostEqual(observed["N", "Q"], 0.000203583)
        self.assertAlmostEqual(observed["N", "R"], 0.000203583)
        self.assertAlmostEqual(observed["N", "S"], 0.001628664)
        self.assertAlmostEqual(observed["N", "T"], 0.000651466)
        self.assertAlmostEqual(observed["N", "V"], 0.000040717)
        self.assertAlmostEqual(observed["N", "W"], 0.000040717)
        self.assertAlmostEqual(observed["N", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["P", "A"], 0.000773616)
        self.assertAlmostEqual(observed["P", "C"], 0.000081433)
        self.assertAlmostEqual(observed["P", "D"], 0.000040717)
        self.assertAlmostEqual(observed["P", "E"], 0.000040717)
        self.assertAlmostEqual(observed["P", "F"], 0.000040717)
        self.assertAlmostEqual(observed["P", "G"], 0.000040717)
        self.assertAlmostEqual(observed["P", "H"], 0.000285016)
        self.assertAlmostEqual(observed["P", "I"], 0.000040717)
        self.assertAlmostEqual(observed["P", "K"], 0.000040717)
        self.assertAlmostEqual(observed["P", "L"], 0.001343648)
        self.assertAlmostEqual(observed["P", "M"], 0.000040717)
        self.assertAlmostEqual(observed["P", "N"], 0.000040717)
        self.assertAlmostEqual(observed["P", "P"], 0.044869707)
        self.assertAlmostEqual(observed["P", "Q"], 0.000162866)
        self.assertAlmostEqual(observed["P", "R"], 0.000285016)
        self.assertAlmostEqual(observed["P", "S"], 0.001750814)
        self.assertAlmostEqual(observed["P", "T"], 0.000651466)
        self.assertAlmostEqual(observed["P", "V"], 0.000162866)
        self.assertAlmostEqual(observed["P", "W"], 0.000040717)
        self.assertAlmostEqual(observed["P", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "A"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "C"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "D"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "E"], 0.000895765)
        self.assertAlmostEqual(observed["Q", "F"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "G"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "H"], 0.000814332)
        self.assertAlmostEqual(observed["Q", "I"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "K"], 0.001058632)
        self.assertAlmostEqual(observed["Q", "L"], 0.000366450)
        self.assertAlmostEqual(observed["Q", "M"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "N"], 0.000203583)
        self.assertAlmostEqual(observed["Q", "P"], 0.000162866)
        self.assertAlmostEqual(observed["Q", "Q"], 0.033306189)
        self.assertAlmostEqual(observed["Q", "R"], 0.001913681)
        self.assertAlmostEqual(observed["Q", "S"], 0.000122150)
        self.assertAlmostEqual(observed["Q", "T"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "V"], 0.000081433)
        self.assertAlmostEqual(observed["Q", "W"], 0.000040717)
        self.assertAlmostEqual(observed["Q", "Y"], 0.000081433)
        self.assertAlmostEqual(observed["R", "A"], 0.000162866)
        self.assertAlmostEqual(observed["R", "C"], 0.000366450)
        self.assertAlmostEqual(observed["R", "D"], 0.000122150)
        self.assertAlmostEqual(observed["R", "E"], 0.000285016)
        self.assertAlmostEqual(observed["R", "F"], 0.000040717)
        self.assertAlmostEqual(observed["R", "G"], 0.001058632)
        self.assertAlmostEqual(observed["R", "H"], 0.001058632)
        self.assertAlmostEqual(observed["R", "I"], 0.000040717)
        self.assertAlmostEqual(observed["R", "K"], 0.003501629)
        self.assertAlmostEqual(observed["R", "L"], 0.000325733)
        self.assertAlmostEqual(observed["R", "M"], 0.000122150)
        self.assertAlmostEqual(observed["R", "N"], 0.000203583)
        self.assertAlmostEqual(observed["R", "P"], 0.000285016)
        self.assertAlmostEqual(observed["R", "Q"], 0.001913681)
        self.assertAlmostEqual(observed["R", "R"], 0.040065147)
        self.assertAlmostEqual(observed["R", "S"], 0.000814332)
        self.assertAlmostEqual(observed["R", "T"], 0.000203583)
        self.assertAlmostEqual(observed["R", "V"], 0.000203583)
        self.assertAlmostEqual(observed["R", "W"], 0.000325733)
        self.assertAlmostEqual(observed["R", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["S", "A"], 0.002280130)
        self.assertAlmostEqual(observed["S", "C"], 0.000366450)
        self.assertAlmostEqual(observed["S", "D"], 0.000244300)
        self.assertAlmostEqual(observed["S", "E"], 0.000244300)
        self.assertAlmostEqual(observed["S", "F"], 0.000610749)
        self.assertAlmostEqual(observed["S", "G"], 0.001628664)
        self.assertAlmostEqual(observed["S", "H"], 0.000203583)
        self.assertAlmostEqual(observed["S", "I"], 0.000244300)
        self.assertAlmostEqual(observed["S", "K"], 0.000162866)
        self.assertAlmostEqual(observed["S", "L"], 0.000488599)
        self.assertAlmostEqual(observed["S", "M"], 0.000081433)
        self.assertAlmostEqual(observed["S", "N"], 0.001628664)
        self.assertAlmostEqual(observed["S", "P"], 0.001750814)
        self.assertAlmostEqual(observed["S", "Q"], 0.000122150)
        self.assertAlmostEqual(observed["S", "R"], 0.000814332)
        self.assertAlmostEqual(observed["S", "S"], 0.065390879)
        self.assertAlmostEqual(observed["S", "T"], 0.002157980)
        self.assertAlmostEqual(observed["S", "V"], 0.000244300)
        self.assertAlmostEqual(observed["S", "W"], 0.000081433)
        self.assertAlmostEqual(observed["S", "Y"], 0.000325733)
        self.assertAlmostEqual(observed["T", "A"], 0.003257329)
        self.assertAlmostEqual(observed["T", "C"], 0.000040717)
        self.assertAlmostEqual(observed["T", "D"], 0.000203583)
        self.assertAlmostEqual(observed["T", "E"], 0.000081433)
        self.assertAlmostEqual(observed["T", "F"], 0.000122150)
        self.assertAlmostEqual(observed["T", "G"], 0.000122150)
        self.assertAlmostEqual(observed["T", "H"], 0.000040717)
        self.assertAlmostEqual(observed["T", "I"], 0.001465798)
        self.assertAlmostEqual(observed["T", "K"], 0.000529316)
        self.assertAlmostEqual(observed["T", "L"], 0.000325733)
        self.assertAlmostEqual(observed["T", "M"], 0.000936482)
        self.assertAlmostEqual(observed["T", "N"], 0.000651466)
        self.assertAlmostEqual(observed["T", "P"], 0.000651466)
        self.assertAlmostEqual(observed["T", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["T", "R"], 0.000203583)
        self.assertAlmostEqual(observed["T", "S"], 0.002157980)
        self.assertAlmostEqual(observed["T", "T"], 0.042833876)
        self.assertAlmostEqual(observed["T", "V"], 0.000773616)
        self.assertAlmostEqual(observed["T", "W"], 0.000081433)
        self.assertAlmostEqual(observed["T", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["V", "A"], 0.002442997)
        self.assertAlmostEqual(observed["V", "C"], 0.000081433)
        self.assertAlmostEqual(observed["V", "D"], 0.000162866)
        self.assertAlmostEqual(observed["V", "E"], 0.000122150)
        self.assertAlmostEqual(observed["V", "F"], 0.000407166)
        self.assertAlmostEqual(observed["V", "G"], 0.000692182)
        self.assertAlmostEqual(observed["V", "H"], 0.000040717)
        self.assertAlmostEqual(observed["V", "I"], 0.004438111)
        self.assertAlmostEqual(observed["V", "K"], 0.000081433)
        self.assertAlmostEqual(observed["V", "L"], 0.002361564)
        self.assertAlmostEqual(observed["V", "M"], 0.000570033)
        self.assertAlmostEqual(observed["V", "N"], 0.000040717)
        self.assertAlmostEqual(observed["V", "P"], 0.000162866)
        self.assertAlmostEqual(observed["V", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["V", "R"], 0.000203583)
        self.assertAlmostEqual(observed["V", "S"], 0.000244300)
        self.assertAlmostEqual(observed["V", "T"], 0.000773616)
        self.assertAlmostEqual(observed["V", "V"], 0.050732899)
        self.assertAlmostEqual(observed["V", "W"], 0.000040717)
        self.assertAlmostEqual(observed["V", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["W", "A"], 0.000081433)
        self.assertAlmostEqual(observed["W", "C"], 0.000081433)
        self.assertAlmostEqual(observed["W", "D"], 0.000040717)
        self.assertAlmostEqual(observed["W", "E"], 0.000040717)
        self.assertAlmostEqual(observed["W", "F"], 0.000040717)
        self.assertAlmostEqual(observed["W", "G"], 0.000244300)
        self.assertAlmostEqual(observed["W", "H"], 0.000040717)
        self.assertAlmostEqual(observed["W", "I"], 0.000040717)
        self.assertAlmostEqual(observed["W", "K"], 0.000040717)
        self.assertAlmostEqual(observed["W", "L"], 0.000162866)
        self.assertAlmostEqual(observed["W", "M"], 0.000040717)
        self.assertAlmostEqual(observed["W", "N"], 0.000040717)
        self.assertAlmostEqual(observed["W", "P"], 0.000040717)
        self.assertAlmostEqual(observed["W", "Q"], 0.000040717)
        self.assertAlmostEqual(observed["W", "R"], 0.000325733)
        self.assertAlmostEqual(observed["W", "S"], 0.000081433)
        self.assertAlmostEqual(observed["W", "T"], 0.000081433)
        self.assertAlmostEqual(observed["W", "V"], 0.000040717)
        self.assertAlmostEqual(observed["W", "W"], 0.013843648)
        self.assertAlmostEqual(observed["W", "Y"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "A"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "C"], 0.000407166)
        self.assertAlmostEqual(observed["Y", "D"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "E"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "F"], 0.001017915)
        self.assertAlmostEqual(observed["Y", "G"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "H"], 0.000895765)
        self.assertAlmostEqual(observed["Y", "I"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "K"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "L"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "M"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "N"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "P"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "Q"], 0.000081433)
        self.assertAlmostEqual(observed["Y", "R"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "S"], 0.000325733)
        self.assertAlmostEqual(observed["Y", "T"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "V"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "W"], 0.000040717)
        self.assertAlmostEqual(observed["Y", "Y"], 0.028664495)

    def test4_aminoacid_probabilities(self):
        """Test calculating expected amino acid probabilities."""
        observed = self.observed
        # calculate probabilities expected under a null model
        probabilities = np.sum(observed, 0)  # Be sure to use numpy's sum
        self.assertEqual(probabilities.shape, (20,))
        self.assertAlmostEqual(probabilities["A"], 0.070358306)
        self.assertAlmostEqual(probabilities["C"], 0.024959283)
        self.assertAlmostEqual(probabilities["D"], 0.041205212)
        self.assertAlmostEqual(probabilities["E"], 0.059120521)
        self.assertAlmostEqual(probabilities["F"], 0.045806189)
        self.assertAlmostEqual(probabilities["G"], 0.057817590)
        self.assertAlmostEqual(probabilities["H"], 0.023208469)
        self.assertAlmostEqual(probabilities["I"], 0.055781759)
        self.assertAlmostEqual(probabilities["K"], 0.055048860)
        self.assertAlmostEqual(probabilities["L"], 0.117793160)
        self.assertAlmostEqual(probabilities["M"], 0.026628664)
        self.assertAlmostEqual(probabilities["N"], 0.036034202)
        self.assertAlmostEqual(probabilities["P"], 0.050773616)
        self.assertAlmostEqual(probabilities["Q"], 0.039413681)
        self.assertAlmostEqual(probabilities["R"], 0.051140065)
        self.assertAlmostEqual(probabilities["S"], 0.079071661)
        self.assertAlmostEqual(probabilities["T"], 0.054600977)
        self.assertAlmostEqual(probabilities["V"], 0.063721498)
        self.assertAlmostEqual(probabilities["W"], 0.015390879)
        self.assertAlmostEqual(probabilities["Y"], 0.032125407)
        TestScoringMatrices.probabilities = probabilities

    def test5_expected_probabilities(self):
        """Test calculating expected amino acid substitution probabilities."""
        probabilities = self.probabilities
        expected = np.dot(probabilities[:, None], probabilities[None, :])
        self.assertEqual(expected.alphabet, protein_alphabet)
        self.assertEqual(expected.shape, (20, 20))
        self.assertAlmostEqual(expected["A", "A"], 0.004950291)
        self.assertAlmostEqual(expected["A", "C"], 0.001756093)
        self.assertAlmostEqual(expected["A", "D"], 0.002899129)
        self.assertAlmostEqual(expected["A", "E"], 0.004159620)
        self.assertAlmostEqual(expected["A", "F"], 0.003222846)
        self.assertAlmostEqual(expected["A", "G"], 0.004067948)
        self.assertAlmostEqual(expected["A", "H"], 0.001632909)
        self.assertAlmostEqual(expected["A", "I"], 0.003924710)
        self.assertAlmostEqual(expected["A", "K"], 0.003873145)
        self.assertAlmostEqual(expected["A", "L"], 0.008287727)
        self.assertAlmostEqual(expected["A", "M"], 0.001873548)
        self.assertAlmostEqual(expected["A", "N"], 0.002535305)
        self.assertAlmostEqual(expected["A", "P"], 0.003572346)
        self.assertAlmostEqual(expected["A", "Q"], 0.002773080)
        self.assertAlmostEqual(expected["A", "R"], 0.003598128)
        self.assertAlmostEqual(expected["A", "S"], 0.005563348)
        self.assertAlmostEqual(expected["A", "T"], 0.003841632)
        self.assertAlmostEqual(expected["A", "V"], 0.004483337)
        self.assertAlmostEqual(expected["A", "W"], 0.001082876)
        self.assertAlmostEqual(expected["A", "Y"], 0.002260289)
        self.assertAlmostEqual(expected["C", "A"], 0.001756093)
        self.assertAlmostEqual(expected["C", "C"], 0.000622966)
        self.assertAlmostEqual(expected["C", "D"], 0.001028453)
        self.assertAlmostEqual(expected["C", "E"], 0.001475606)
        self.assertAlmostEqual(expected["C", "F"], 0.001143290)
        self.assertAlmostEqual(expected["C", "G"], 0.001443086)
        self.assertAlmostEqual(expected["C", "H"], 0.000579267)
        self.assertAlmostEqual(expected["C", "I"], 0.001392273)
        self.assertAlmostEqual(expected["C", "K"], 0.001373980)
        self.assertAlmostEqual(expected["C", "L"], 0.002940033)
        self.assertAlmostEqual(expected["C", "M"], 0.000664632)
        self.assertAlmostEqual(expected["C", "N"], 0.000899388)
        self.assertAlmostEqual(expected["C", "P"], 0.001267273)
        self.assertAlmostEqual(expected["C", "Q"], 0.000983737)
        self.assertAlmostEqual(expected["C", "R"], 0.001276419)
        self.assertAlmostEqual(expected["C", "S"], 0.001973572)
        self.assertAlmostEqual(expected["C", "T"], 0.001362801)
        self.assertAlmostEqual(expected["C", "V"], 0.001590443)
        self.assertAlmostEqual(expected["C", "W"], 0.000384145)
        self.assertAlmostEqual(expected["C", "Y"], 0.000801827)
        self.assertAlmostEqual(expected["D", "A"], 0.002899129)
        self.assertAlmostEqual(expected["D", "C"], 0.001028453)
        self.assertAlmostEqual(expected["D", "D"], 0.001697869)
        self.assertAlmostEqual(expected["D", "E"], 0.002436074)
        self.assertAlmostEqual(expected["D", "F"], 0.001887454)
        self.assertAlmostEqual(expected["D", "G"], 0.002382386)
        self.assertAlmostEqual(expected["D", "H"], 0.000956310)
        self.assertAlmostEqual(expected["D", "I"], 0.002298499)
        self.assertAlmostEqual(expected["D", "K"], 0.002268300)
        self.assertAlmostEqual(expected["D", "L"], 0.004853692)
        self.assertAlmostEqual(expected["D", "M"], 0.001097240)
        self.assertAlmostEqual(expected["D", "N"], 0.001484797)
        self.assertAlmostEqual(expected["D", "P"], 0.002092138)
        self.assertAlmostEqual(expected["D", "Q"], 0.001624049)
        self.assertAlmostEqual(expected["D", "R"], 0.002107237)
        self.assertAlmostEqual(expected["D", "S"], 0.003258165)
        self.assertAlmostEqual(expected["D", "T"], 0.002249845)
        self.assertAlmostEqual(expected["D", "V"], 0.002625658)
        self.assertAlmostEqual(expected["D", "W"], 0.000634184)
        self.assertAlmostEqual(expected["D", "Y"], 0.001323734)
        self.assertAlmostEqual(expected["E", "A"], 0.004159620)
        self.assertAlmostEqual(expected["E", "C"], 0.001475606)
        self.assertAlmostEqual(expected["E", "D"], 0.002436074)
        self.assertAlmostEqual(expected["E", "E"], 0.003495236)
        self.assertAlmostEqual(expected["E", "F"], 0.002708086)
        self.assertAlmostEqual(expected["E", "G"], 0.003418206)
        self.assertAlmostEqual(expected["E", "H"], 0.001372097)
        self.assertAlmostEqual(expected["E", "I"], 0.003297847)
        self.assertAlmostEqual(expected["E", "K"], 0.003254517)
        self.assertAlmostEqual(expected["E", "L"], 0.006963993)
        self.assertAlmostEqual(expected["E", "M"], 0.001574301)
        self.assertAlmostEqual(expected["E", "N"], 0.002130361)
        self.assertAlmostEqual(expected["E", "P"], 0.003001763)
        self.assertAlmostEqual(expected["E", "Q"], 0.002330157)
        self.assertAlmostEqual(expected["E", "R"], 0.003023427)
        self.assertAlmostEqual(expected["E", "S"], 0.004674758)
        self.assertAlmostEqual(expected["E", "T"], 0.003228038)
        self.assertAlmostEqual(expected["E", "V"], 0.003767248)
        self.assertAlmostEqual(expected["E", "W"], 0.000909917)
        self.assertAlmostEqual(expected["E", "Y"], 0.001899271)
        self.assertAlmostEqual(expected["F", "A"], 0.003222846)
        self.assertAlmostEqual(expected["F", "C"], 0.001143290)
        self.assertAlmostEqual(expected["F", "D"], 0.001887454)
        self.assertAlmostEqual(expected["F", "E"], 0.002708086)
        self.assertAlmostEqual(expected["F", "F"], 0.002098207)
        self.assertAlmostEqual(expected["F", "G"], 0.002648403)
        self.assertAlmostEqual(expected["F", "H"], 0.001063092)
        self.assertAlmostEqual(expected["F", "I"], 0.002555150)
        self.assertAlmostEqual(expected["F", "K"], 0.002521578)
        self.assertAlmostEqual(expected["F", "L"], 0.005395656)
        self.assertAlmostEqual(expected["F", "M"], 0.001219758)
        self.assertAlmostEqual(expected["F", "N"], 0.001650589)
        self.assertAlmostEqual(expected["F", "P"], 0.002325746)
        self.assertAlmostEqual(expected["F", "Q"], 0.001805391)
        self.assertAlmostEqual(expected["F", "R"], 0.002342531)
        self.assertAlmostEqual(expected["F", "S"], 0.003621971)
        self.assertAlmostEqual(expected["F", "T"], 0.002501063)
        self.assertAlmostEqual(expected["F", "V"], 0.002918839)
        self.assertAlmostEqual(expected["F", "W"], 0.000704998)
        self.assertAlmostEqual(expected["F", "Y"], 0.001471542)
        self.assertAlmostEqual(expected["G", "A"], 0.004067948)
        self.assertAlmostEqual(expected["G", "C"], 0.001443086)
        self.assertAlmostEqual(expected["G", "D"], 0.002382386)
        self.assertAlmostEqual(expected["G", "E"], 0.003418206)
        self.assertAlmostEqual(expected["G", "F"], 0.002648403)
        self.assertAlmostEqual(expected["G", "G"], 0.003342874)
        self.assertAlmostEqual(expected["G", "H"], 0.001341858)
        self.assertAlmostEqual(expected["G", "I"], 0.003225167)
        self.assertAlmostEqual(expected["G", "K"], 0.003182792)
        self.assertAlmostEqual(expected["G", "L"], 0.006810517)
        self.assertAlmostEqual(expected["G", "M"], 0.001539605)
        self.assertAlmostEqual(expected["G", "N"], 0.002083411)
        self.assertAlmostEqual(expected["G", "P"], 0.002935608)
        self.assertAlmostEqual(expected["G", "Q"], 0.002278804)
        self.assertAlmostEqual(expected["G", "R"], 0.002956795)
        self.assertAlmostEqual(expected["G", "S"], 0.004571733)
        self.assertAlmostEqual(expected["G", "T"], 0.003156897)
        self.assertAlmostEqual(expected["G", "V"], 0.003684223)
        self.assertAlmostEqual(expected["G", "W"], 0.000889864)
        self.assertAlmostEqual(expected["G", "Y"], 0.001857414)
        self.assertAlmostEqual(expected["H", "A"], 0.001632909)
        self.assertAlmostEqual(expected["H", "C"], 0.000579267)
        self.assertAlmostEqual(expected["H", "D"], 0.000956310)
        self.assertAlmostEqual(expected["H", "E"], 0.001372097)
        self.assertAlmostEqual(expected["H", "F"], 0.001063092)
        self.assertAlmostEqual(expected["H", "G"], 0.001341858)
        self.assertAlmostEqual(expected["H", "H"], 0.000538633)
        self.assertAlmostEqual(expected["H", "I"], 0.001294609)
        self.assertAlmostEqual(expected["H", "K"], 0.001277600)
        self.assertAlmostEqual(expected["H", "L"], 0.002733799)
        self.assertAlmostEqual(expected["H", "M"], 0.000618011)
        self.assertAlmostEqual(expected["H", "N"], 0.000836299)
        self.assertAlmostEqual(expected["H", "P"], 0.001178378)
        self.assertAlmostEqual(expected["H", "Q"], 0.000914731)
        self.assertAlmostEqual(expected["H", "R"], 0.001186883)
        self.assertAlmostEqual(expected["H", "S"], 0.001835132)
        self.assertAlmostEqual(expected["H", "T"], 0.001267205)
        self.assertAlmostEqual(expected["H", "V"], 0.001478878)
        self.assertAlmostEqual(expected["H", "W"], 0.000357199)
        self.assertAlmostEqual(expected["H", "Y"], 0.000745582)
        self.assertAlmostEqual(expected["I", "A"], 0.003924710)
        self.assertAlmostEqual(expected["I", "C"], 0.001392273)
        self.assertAlmostEqual(expected["I", "D"], 0.002298499)
        self.assertAlmostEqual(expected["I", "E"], 0.003297847)
        self.assertAlmostEqual(expected["I", "F"], 0.002555150)
        self.assertAlmostEqual(expected["I", "G"], 0.003225167)
        self.assertAlmostEqual(expected["I", "H"], 0.001294609)
        self.assertAlmostEqual(expected["I", "I"], 0.003111605)
        self.assertAlmostEqual(expected["I", "K"], 0.003070722)
        self.assertAlmostEqual(expected["I", "L"], 0.006570710)
        self.assertAlmostEqual(expected["I", "M"], 0.001485394)
        self.assertAlmostEqual(expected["I", "N"], 0.002010051)
        self.assertAlmostEqual(expected["I", "P"], 0.002832242)
        self.assertAlmostEqual(expected["I", "Q"], 0.002198564)
        self.assertAlmostEqual(expected["I", "R"], 0.002852683)
        self.assertAlmostEqual(expected["I", "S"], 0.004410756)
        self.assertAlmostEqual(expected["I", "T"], 0.003045739)
        self.assertAlmostEqual(expected["I", "V"], 0.003554497)
        self.assertAlmostEqual(expected["I", "W"], 0.000858530)
        self.assertAlmostEqual(expected["I", "Y"], 0.001792012)
        self.assertAlmostEqual(expected["K", "A"], 0.003873145)
        self.assertAlmostEqual(expected["K", "C"], 0.001373980)
        self.assertAlmostEqual(expected["K", "D"], 0.002268300)
        self.assertAlmostEqual(expected["K", "E"], 0.003254517)
        self.assertAlmostEqual(expected["K", "F"], 0.002521578)
        self.assertAlmostEqual(expected["K", "G"], 0.003182792)
        self.assertAlmostEqual(expected["K", "H"], 0.001277600)
        self.assertAlmostEqual(expected["K", "I"], 0.003070722)
        self.assertAlmostEqual(expected["K", "K"], 0.003030377)
        self.assertAlmostEqual(expected["K", "L"], 0.006484379)
        self.assertAlmostEqual(expected["K", "M"], 0.001465878)
        self.assertAlmostEqual(expected["K", "N"], 0.001983642)
        self.assertAlmostEqual(expected["K", "P"], 0.002795030)
        self.assertAlmostEqual(expected["K", "Q"], 0.002169678)
        self.assertAlmostEqual(expected["K", "R"], 0.002815202)
        self.assertAlmostEqual(expected["K", "S"], 0.004352805)
        self.assertAlmostEqual(expected["K", "T"], 0.003005722)
        self.assertAlmostEqual(expected["K", "V"], 0.003507796)
        self.assertAlmostEqual(expected["K", "W"], 0.000847250)
        self.assertAlmostEqual(expected["K", "Y"], 0.001768467)
        self.assertAlmostEqual(expected["L", "A"], 0.008287727)
        self.assertAlmostEqual(expected["L", "C"], 0.002940033)
        self.assertAlmostEqual(expected["L", "D"], 0.004853692)
        self.assertAlmostEqual(expected["L", "E"], 0.006963993)
        self.assertAlmostEqual(expected["L", "F"], 0.005395656)
        self.assertAlmostEqual(expected["L", "G"], 0.006810517)
        self.assertAlmostEqual(expected["L", "H"], 0.002733799)
        self.assertAlmostEqual(expected["L", "I"], 0.006570710)
        self.assertAlmostEqual(expected["L", "K"], 0.006484379)
        self.assertAlmostEqual(expected["L", "L"], 0.013875228)
        self.assertAlmostEqual(expected["L", "M"], 0.003136675)
        self.assertAlmostEqual(expected["L", "N"], 0.004244583)
        self.assertAlmostEqual(expected["L", "P"], 0.005980785)
        self.assertAlmostEqual(expected["L", "Q"], 0.004642662)
        self.assertAlmostEqual(expected["L", "R"], 0.006023950)
        self.assertAlmostEqual(expected["L", "S"], 0.009314101)
        self.assertAlmostEqual(expected["L", "T"], 0.006431622)
        self.assertAlmostEqual(expected["L", "V"], 0.007505957)
        self.assertAlmostEqual(expected["L", "W"], 0.001812940)
        self.assertAlmostEqual(expected["L", "Y"], 0.003784153)
        self.assertAlmostEqual(expected["M", "A"], 0.001873548)
        self.assertAlmostEqual(expected["M", "C"], 0.000664632)
        self.assertAlmostEqual(expected["M", "D"], 0.001097240)
        self.assertAlmostEqual(expected["M", "E"], 0.001574301)
        self.assertAlmostEqual(expected["M", "F"], 0.001219758)
        self.assertAlmostEqual(expected["M", "G"], 0.001539605)
        self.assertAlmostEqual(expected["M", "H"], 0.000618011)
        self.assertAlmostEqual(expected["M", "I"], 0.001485394)
        self.assertAlmostEqual(expected["M", "K"], 0.001465878)
        self.assertAlmostEqual(expected["M", "L"], 0.003136675)
        self.assertAlmostEqual(expected["M", "M"], 0.000709086)
        self.assertAlmostEqual(expected["M", "N"], 0.000959543)
        self.assertAlmostEqual(expected["M", "P"], 0.001352034)
        self.assertAlmostEqual(expected["M", "Q"], 0.001049534)
        self.assertAlmostEqual(expected["M", "R"], 0.001361792)
        self.assertAlmostEqual(expected["M", "S"], 0.002105573)
        self.assertAlmostEqual(expected["M", "T"], 0.001453951)
        self.assertAlmostEqual(expected["M", "V"], 0.001696818)
        self.assertAlmostEqual(expected["M", "W"], 0.000409839)
        self.assertAlmostEqual(expected["M", "Y"], 0.000855457)
        self.assertAlmostEqual(expected["N", "A"], 0.002535305)
        self.assertAlmostEqual(expected["N", "C"], 0.000899388)
        self.assertAlmostEqual(expected["N", "D"], 0.001484797)
        self.assertAlmostEqual(expected["N", "E"], 0.002130361)
        self.assertAlmostEqual(expected["N", "F"], 0.001650589)
        self.assertAlmostEqual(expected["N", "G"], 0.002083411)
        self.assertAlmostEqual(expected["N", "H"], 0.000836299)
        self.assertAlmostEqual(expected["N", "I"], 0.002010051)
        self.assertAlmostEqual(expected["N", "K"], 0.001983642)
        self.assertAlmostEqual(expected["N", "L"], 0.004244583)
        self.assertAlmostEqual(expected["N", "M"], 0.000959543)
        self.assertAlmostEqual(expected["N", "N"], 0.001298464)
        self.assertAlmostEqual(expected["N", "P"], 0.001829587)
        self.assertAlmostEqual(expected["N", "Q"], 0.001420241)
        self.assertAlmostEqual(expected["N", "R"], 0.001842791)
        self.assertAlmostEqual(expected["N", "S"], 0.002849284)
        self.assertAlmostEqual(expected["N", "T"], 0.001967503)
        self.assertAlmostEqual(expected["N", "V"], 0.002296153)
        self.assertAlmostEqual(expected["N", "W"], 0.000554598)
        self.assertAlmostEqual(expected["N", "Y"], 0.001157613)
        self.assertAlmostEqual(expected["P", "A"], 0.003572346)
        self.assertAlmostEqual(expected["P", "C"], 0.001267273)
        self.assertAlmostEqual(expected["P", "D"], 0.002092138)
        self.assertAlmostEqual(expected["P", "E"], 0.003001763)
        self.assertAlmostEqual(expected["P", "F"], 0.002325746)
        self.assertAlmostEqual(expected["P", "G"], 0.002935608)
        self.assertAlmostEqual(expected["P", "H"], 0.001178378)
        self.assertAlmostEqual(expected["P", "I"], 0.002832242)
        self.assertAlmostEqual(expected["P", "K"], 0.002795030)
        self.assertAlmostEqual(expected["P", "L"], 0.005980785)
        self.assertAlmostEqual(expected["P", "M"], 0.001352034)
        self.assertAlmostEqual(expected["P", "N"], 0.001829587)
        self.assertAlmostEqual(expected["P", "P"], 0.002577960)
        self.assertAlmostEqual(expected["P", "Q"], 0.002001175)
        self.assertAlmostEqual(expected["P", "R"], 0.002596566)
        self.assertAlmostEqual(expected["P", "S"], 0.004014754)
        self.assertAlmostEqual(expected["P", "T"], 0.002772289)
        self.assertAlmostEqual(expected["P", "V"], 0.003235371)
        self.assertAlmostEqual(expected["P", "W"], 0.000781451)
        self.assertAlmostEqual(expected["P", "Y"], 0.001631123)
        self.assertAlmostEqual(expected["Q", "A"], 0.002773080)
        self.assertAlmostEqual(expected["Q", "C"], 0.000983737)
        self.assertAlmostEqual(expected["Q", "D"], 0.001624049)
        self.assertAlmostEqual(expected["Q", "E"], 0.002330157)
        self.assertAlmostEqual(expected["Q", "F"], 0.001805391)
        self.assertAlmostEqual(expected["Q", "G"], 0.002278804)
        self.assertAlmostEqual(expected["Q", "H"], 0.000914731)
        self.assertAlmostEqual(expected["Q", "I"], 0.002198564)
        self.assertAlmostEqual(expected["Q", "K"], 0.002169678)
        self.assertAlmostEqual(expected["Q", "L"], 0.004642662)
        self.assertAlmostEqual(expected["Q", "M"], 0.001049534)
        self.assertAlmostEqual(expected["Q", "N"], 0.001420241)
        self.assertAlmostEqual(expected["Q", "P"], 0.002001175)
        self.assertAlmostEqual(expected["Q", "Q"], 0.001553438)
        self.assertAlmostEqual(expected["Q", "R"], 0.002015618)
        self.assertAlmostEqual(expected["Q", "S"], 0.003116505)
        self.assertAlmostEqual(expected["Q", "T"], 0.002152025)
        self.assertAlmostEqual(expected["Q", "V"], 0.002511499)
        self.assertAlmostEqual(expected["Q", "W"], 0.000606611)
        self.assertAlmostEqual(expected["Q", "Y"], 0.001266181)
        self.assertAlmostEqual(expected["R", "A"], 0.003598128)
        self.assertAlmostEqual(expected["R", "C"], 0.001276419)
        self.assertAlmostEqual(expected["R", "D"], 0.002107237)
        self.assertAlmostEqual(expected["R", "E"], 0.003023427)
        self.assertAlmostEqual(expected["R", "F"], 0.002342531)
        self.assertAlmostEqual(expected["R", "G"], 0.002956795)
        self.assertAlmostEqual(expected["R", "H"], 0.001186883)
        self.assertAlmostEqual(expected["R", "I"], 0.002852683)
        self.assertAlmostEqual(expected["R", "K"], 0.002815202)
        self.assertAlmostEqual(expected["R", "L"], 0.006023950)
        self.assertAlmostEqual(expected["R", "M"], 0.001361792)
        self.assertAlmostEqual(expected["R", "N"], 0.001842791)
        self.assertAlmostEqual(expected["R", "P"], 0.002596566)
        self.assertAlmostEqual(expected["R", "Q"], 0.002015618)
        self.assertAlmostEqual(expected["R", "R"], 0.002615306)
        self.assertAlmostEqual(expected["R", "S"], 0.004043730)
        self.assertAlmostEqual(expected["R", "T"], 0.002792298)
        self.assertAlmostEqual(expected["R", "V"], 0.003258722)
        self.assertAlmostEqual(expected["R", "W"], 0.000787091)
        self.assertAlmostEqual(expected["R", "Y"], 0.001642895)
        self.assertAlmostEqual(expected["S", "A"], 0.005563348)
        self.assertAlmostEqual(expected["S", "C"], 0.001973572)
        self.assertAlmostEqual(expected["S", "D"], 0.003258165)
        self.assertAlmostEqual(expected["S", "E"], 0.004674758)
        self.assertAlmostEqual(expected["S", "F"], 0.003621971)
        self.assertAlmostEqual(expected["S", "G"], 0.004571733)
        self.assertAlmostEqual(expected["S", "H"], 0.001835132)
        self.assertAlmostEqual(expected["S", "I"], 0.004410756)
        self.assertAlmostEqual(expected["S", "K"], 0.004352805)
        self.assertAlmostEqual(expected["S", "L"], 0.009314101)
        self.assertAlmostEqual(expected["S", "M"], 0.002105573)
        self.assertAlmostEqual(expected["S", "N"], 0.002849284)
        self.assertAlmostEqual(expected["S", "P"], 0.004014754)
        self.assertAlmostEqual(expected["S", "Q"], 0.003116505)
        self.assertAlmostEqual(expected["S", "R"], 0.004043730)
        self.assertAlmostEqual(expected["S", "S"], 0.006252328)
        self.assertAlmostEqual(expected["S", "T"], 0.004317390)
        self.assertAlmostEqual(expected["S", "V"], 0.005038565)
        self.assertAlmostEqual(expected["S", "W"], 0.001216982)
        self.assertAlmostEqual(expected["S", "Y"], 0.002540209)
        self.assertAlmostEqual(expected["T", "A"], 0.003841632)
        self.assertAlmostEqual(expected["T", "C"], 0.001362801)
        self.assertAlmostEqual(expected["T", "D"], 0.002249845)
        self.assertAlmostEqual(expected["T", "E"], 0.003228038)
        self.assertAlmostEqual(expected["T", "F"], 0.002501063)
        self.assertAlmostEqual(expected["T", "G"], 0.003156897)
        self.assertAlmostEqual(expected["T", "H"], 0.001267205)
        self.assertAlmostEqual(expected["T", "I"], 0.003045739)
        self.assertAlmostEqual(expected["T", "K"], 0.003005722)
        self.assertAlmostEqual(expected["T", "L"], 0.006431622)
        self.assertAlmostEqual(expected["T", "M"], 0.001453951)
        self.assertAlmostEqual(expected["T", "N"], 0.001967503)
        self.assertAlmostEqual(expected["T", "P"], 0.002772289)
        self.assertAlmostEqual(expected["T", "Q"], 0.002152025)
        self.assertAlmostEqual(expected["T", "R"], 0.002792298)
        self.assertAlmostEqual(expected["T", "S"], 0.004317390)
        self.assertAlmostEqual(expected["T", "T"], 0.002981267)
        self.assertAlmostEqual(expected["T", "V"], 0.003479256)
        self.assertAlmostEqual(expected["T", "W"], 0.000840357)
        self.assertAlmostEqual(expected["T", "Y"], 0.001754079)
        self.assertAlmostEqual(expected["V", "A"], 0.004483337)
        self.assertAlmostEqual(expected["V", "C"], 0.001590443)
        self.assertAlmostEqual(expected["V", "D"], 0.002625658)
        self.assertAlmostEqual(expected["V", "E"], 0.003767248)
        self.assertAlmostEqual(expected["V", "F"], 0.002918839)
        self.assertAlmostEqual(expected["V", "G"], 0.003684223)
        self.assertAlmostEqual(expected["V", "H"], 0.001478878)
        self.assertAlmostEqual(expected["V", "I"], 0.003554497)
        self.assertAlmostEqual(expected["V", "K"], 0.003507796)
        self.assertAlmostEqual(expected["V", "L"], 0.007505957)
        self.assertAlmostEqual(expected["V", "M"], 0.001696818)
        self.assertAlmostEqual(expected["V", "N"], 0.002296153)
        self.assertAlmostEqual(expected["V", "P"], 0.003235371)
        self.assertAlmostEqual(expected["V", "Q"], 0.002511499)
        self.assertAlmostEqual(expected["V", "R"], 0.003258722)
        self.assertAlmostEqual(expected["V", "S"], 0.005038565)
        self.assertAlmostEqual(expected["V", "T"], 0.003479256)
        self.assertAlmostEqual(expected["V", "V"], 0.004060429)
        self.assertAlmostEqual(expected["V", "W"], 0.000980730)
        self.assertAlmostEqual(expected["V", "Y"], 0.002047079)
        self.assertAlmostEqual(expected["W", "A"], 0.001082876)
        self.assertAlmostEqual(expected["W", "C"], 0.000384145)
        self.assertAlmostEqual(expected["W", "D"], 0.000634184)
        self.assertAlmostEqual(expected["W", "E"], 0.000909917)
        self.assertAlmostEqual(expected["W", "F"], 0.000704998)
        self.assertAlmostEqual(expected["W", "G"], 0.000889864)
        self.assertAlmostEqual(expected["W", "H"], 0.000357199)
        self.assertAlmostEqual(expected["W", "I"], 0.000858530)
        self.assertAlmostEqual(expected["W", "K"], 0.000847250)
        self.assertAlmostEqual(expected["W", "L"], 0.001812940)
        self.assertAlmostEqual(expected["W", "M"], 0.000409839)
        self.assertAlmostEqual(expected["W", "N"], 0.000554598)
        self.assertAlmostEqual(expected["W", "P"], 0.000781451)
        self.assertAlmostEqual(expected["W", "Q"], 0.000606611)
        self.assertAlmostEqual(expected["W", "R"], 0.000787091)
        self.assertAlmostEqual(expected["W", "S"], 0.001216982)
        self.assertAlmostEqual(expected["W", "T"], 0.000840357)
        self.assertAlmostEqual(expected["W", "V"], 0.000980730)
        self.assertAlmostEqual(expected["W", "W"], 0.000236879)
        self.assertAlmostEqual(expected["W", "Y"], 0.000494438)
        self.assertAlmostEqual(expected["Y", "A"], 0.002260289)
        self.assertAlmostEqual(expected["Y", "C"], 0.000801827)
        self.assertAlmostEqual(expected["Y", "D"], 0.001323734)
        self.assertAlmostEqual(expected["Y", "E"], 0.001899271)
        self.assertAlmostEqual(expected["Y", "F"], 0.001471542)
        self.assertAlmostEqual(expected["Y", "G"], 0.001857414)
        self.assertAlmostEqual(expected["Y", "H"], 0.000745582)
        self.assertAlmostEqual(expected["Y", "I"], 0.001792012)
        self.assertAlmostEqual(expected["Y", "K"], 0.001768467)
        self.assertAlmostEqual(expected["Y", "L"], 0.003784153)
        self.assertAlmostEqual(expected["Y", "M"], 0.000855457)
        self.assertAlmostEqual(expected["Y", "N"], 0.001157613)
        self.assertAlmostEqual(expected["Y", "P"], 0.001631123)
        self.assertAlmostEqual(expected["Y", "Q"], 0.001266181)
        self.assertAlmostEqual(expected["Y", "R"], 0.001642895)
        self.assertAlmostEqual(expected["Y", "S"], 0.002540209)
        self.assertAlmostEqual(expected["Y", "T"], 0.001754079)
        self.assertAlmostEqual(expected["Y", "V"], 0.002047079)
        self.assertAlmostEqual(expected["Y", "W"], 0.000494438)
        self.assertAlmostEqual(expected["Y", "Y"], 0.001032042)
        TestScoringMatrices.expected = expected

    def test6_scores(self):
        """Test calculating amino acid substitution log-ratios."""
        observed = self.observed
        expected = self.expected
        # calculate the log-ratio
        scores = np.log2(observed / expected)
        self.assertEqual(scores.alphabet, protein_alphabet)
        self.assertEqual(scores.shape, (20, 20))
        self.assertAlmostEqual(scores["A", "A"], 3.537772309)
        self.assertAlmostEqual(scores["A", "C"], -5.430607826)
        self.assertAlmostEqual(scores["A", "D"], -2.831930042)
        self.assertAlmostEqual(scores["A", "E"], -2.352762205)
        self.assertAlmostEqual(scores["A", "F"], -6.306573848)
        self.assertAlmostEqual(scores["A", "G"], -1.942100058)
        self.assertAlmostEqual(scores["A", "H"], -4.325682671)
        self.assertAlmostEqual(scores["A", "I"], -3.420899738)
        self.assertAlmostEqual(scores["A", "K"], -4.571743998)
        self.assertAlmostEqual(scores["A", "L"], -4.084252669)
        self.assertAlmostEqual(scores["A", "M"], -3.202083293)
        self.assertAlmostEqual(scores["A", "N"], -4.375435706)
        self.assertAlmostEqual(scores["A", "P"], -2.207182798)
        self.assertAlmostEqual(scores["A", "Q"], -6.089727799)
        self.assertAlmostEqual(scores["A", "R"], -4.465485311)
        self.assertAlmostEqual(scores["A", "S"], -1.286837125)
        self.assertAlmostEqual(scores["A", "T"], -0.238029989)
        self.assertAlmostEqual(scores["A", "V"], -0.875920908)
        self.assertAlmostEqual(scores["A", "W"], -3.733106986)
        self.assertAlmostEqual(scores["A", "Y"], -5.794746052)
        self.assertAlmostEqual(scores["C", "A"], -5.430607826)
        self.assertAlmostEqual(scores["C", "C"], 5.188657725)
        self.assertAlmostEqual(scores["C", "D"], -4.658713898)
        self.assertAlmostEqual(scores["C", "E"], -5.179546061)
        self.assertAlmostEqual(scores["C", "F"], -2.489501515)
        self.assertAlmostEqual(scores["C", "G"], -3.147395538)
        self.assertAlmostEqual(scores["C", "H"], -3.830538432)
        self.assertAlmostEqual(scores["C", "I"], -5.095680501)
        self.assertAlmostEqual(scores["C", "K"], -5.076599760)
        self.assertAlmostEqual(scores["C", "L"], -5.174070931)
        self.assertAlmostEqual(scores["C", "M"], -4.028867149)
        self.assertAlmostEqual(scores["C", "N"], -4.465253968)
        self.assertAlmostEqual(scores["C", "P"], -3.959966073)
        self.assertAlmostEqual(scores["C", "Q"], -4.594583561)
        self.assertAlmostEqual(scores["C", "R"], -1.800416071)
        self.assertAlmostEqual(scores["C", "S"], -2.429122807)
        self.assertAlmostEqual(scores["C", "T"], -5.064813845)
        self.assertAlmostEqual(scores["C", "V"], -4.287667265)
        self.assertAlmostEqual(scores["C", "W"], -2.237962748)
        self.assertAlmostEqual(scores["C", "Y"], -0.977673719)
        self.assertAlmostEqual(scores["D", "A"], -2.831930042)
        self.assertAlmostEqual(scores["D", "C"], -4.658713898)
        self.assertAlmostEqual(scores["D", "D"], 4.356128050)
        self.assertAlmostEqual(scores["D", "E"], -0.121436659)
        self.assertAlmostEqual(scores["D", "F"], -5.534679921)
        self.assertAlmostEqual(scores["D", "G"], -1.700720847)
        self.assertAlmostEqual(scores["D", "H"], -2.553788743)
        self.assertAlmostEqual(scores["D", "I"], -5.818930812)
        self.assertAlmostEqual(scores["D", "K"], -4.799850071)
        self.assertAlmostEqual(scores["D", "L"], -5.897321242)
        self.assertAlmostEqual(scores["D", "M"], -4.752117460)
        self.assertAlmostEqual(scores["D", "N"], 0.133423815)
        self.assertAlmostEqual(scores["D", "P"], -5.683216384)
        self.assertAlmostEqual(scores["D", "Q"], -5.317833872)
        self.assertAlmostEqual(scores["D", "R"], -4.108628883)
        self.assertAlmostEqual(scores["D", "S"], -3.737335619)
        self.assertAlmostEqual(scores["D", "T"], -3.466136061)
        self.assertAlmostEqual(scores["D", "V"], -4.010917576)
        self.assertAlmostEqual(scores["D", "W"], -3.961213059)
        self.assertAlmostEqual(scores["D", "Y"], -4.022852124)
        self.assertAlmostEqual(scores["E", "A"], -2.352762205)
        self.assertAlmostEqual(scores["E", "C"], -5.179546061)
        self.assertAlmostEqual(scores["E", "D"], -0.121436659)
        self.assertAlmostEqual(scores["E", "E"], 3.873287671)
        self.assertAlmostEqual(scores["E", "F"], -6.055512084)
        self.assertAlmostEqual(scores["E", "G"], -1.347083893)
        self.assertAlmostEqual(scores["E", "H"], -3.074620907)
        self.assertAlmostEqual(scores["E", "I"], -4.754800475)
        self.assertAlmostEqual(scores["E", "K"], -1.462701239)
        self.assertAlmostEqual(scores["E", "L"], -6.418153406)
        self.assertAlmostEqual(scores["E", "M"], -5.272949623)
        self.assertAlmostEqual(scores["E", "N"], -4.709336443)
        self.assertAlmostEqual(scores["E", "P"], -6.204048548)
        self.assertAlmostEqual(scores["E", "Q"], -1.379234416)
        self.assertAlmostEqual(scores["E", "R"], -3.407068625)
        self.assertAlmostEqual(scores["E", "S"], -4.258167782)
        self.assertAlmostEqual(scores["E", "T"], -5.308896320)
        self.assertAlmostEqual(scores["E", "V"], -4.946787239)
        self.assertAlmostEqual(scores["E", "W"], -4.482045222)
        self.assertAlmostEqual(scores["E", "Y"], -5.543684288)
        self.assertAlmostEqual(scores["F", "A"], -6.306573848)
        self.assertAlmostEqual(scores["F", "C"], -2.489501515)
        self.assertAlmostEqual(scores["F", "D"], -5.534679921)
        self.assertAlmostEqual(scores["F", "E"], -6.055512084)
        self.assertAlmostEqual(scores["F", "F"], 4.269706410)
        self.assertAlmostEqual(scores["F", "G"], -6.023361560)
        self.assertAlmostEqual(scores["F", "H"], -3.706504455)
        self.assertAlmostEqual(scores["F", "I"], -3.386684023)
        self.assertAlmostEqual(scores["F", "K"], -5.952565782)
        self.assertAlmostEqual(scores["F", "L"], -1.349597236)
        self.assertAlmostEqual(scores["F", "M"], -3.904833171)
        self.assertAlmostEqual(scores["F", "N"], -4.341219991)
        self.assertAlmostEqual(scores["F", "P"], -5.835932096)
        self.assertAlmostEqual(scores["F", "Q"], -5.470549583)
        self.assertAlmostEqual(scores["F", "R"], -5.846307095)
        self.assertAlmostEqual(scores["F", "S"], -2.568123236)
        self.assertAlmostEqual(scores["F", "T"], -4.355817367)
        self.assertAlmostEqual(scores["F", "V"], -2.841705193)
        self.assertAlmostEqual(scores["F", "W"], -4.113928770)
        self.assertAlmostEqual(scores["F", "Y"], -0.531711646)
        self.assertAlmostEqual(scores["G", "A"], -1.942100058)
        self.assertAlmostEqual(scores["G", "C"], -3.147395538)
        self.assertAlmostEqual(scores["G", "D"], -1.700720847)
        self.assertAlmostEqual(scores["G", "E"], -1.347083893)
        self.assertAlmostEqual(scores["G", "F"], -6.023361560)
        self.assertAlmostEqual(scores["G", "G"], 3.898060354)
        self.assertAlmostEqual(scores["G", "H"], -4.042470383)
        self.assertAlmostEqual(scores["G", "I"], -6.307612452)
        self.assertAlmostEqual(scores["G", "K"], -4.703569210)
        self.assertAlmostEqual(scores["G", "L"], -5.801040381)
        self.assertAlmostEqual(scores["G", "M"], -3.655836599)
        self.assertAlmostEqual(scores["G", "N"], -2.869830997)
        self.assertAlmostEqual(scores["G", "P"], -6.171898024)
        self.assertAlmostEqual(scores["G", "Q"], -5.806515511)
        self.assertAlmostEqual(scores["G", "R"], -1.481833305)
        self.assertAlmostEqual(scores["G", "S"], -1.489051665)
        self.assertAlmostEqual(scores["G", "T"], -4.691783295)
        self.assertAlmostEqual(scores["G", "V"], -2.412136375)
        self.assertAlmostEqual(scores["G", "W"], -1.864932198)
        self.assertAlmostEqual(scores["G", "Y"], -5.511533764)
        self.assertAlmostEqual(scores["H", "A"], -4.325682671)
        self.assertAlmostEqual(scores["H", "C"], -3.830538432)
        self.assertAlmostEqual(scores["H", "D"], -2.553788743)
        self.assertAlmostEqual(scores["H", "E"], -3.074620907)
        self.assertAlmostEqual(scores["H", "F"], -3.706504455)
        self.assertAlmostEqual(scores["H", "G"], -4.042470383)
        self.assertAlmostEqual(scores["H", "H"], 5.100935209)
        self.assertAlmostEqual(scores["H", "I"], -4.990755347)
        self.assertAlmostEqual(scores["H", "K"], -3.386712104)
        self.assertAlmostEqual(scores["H", "L"], -5.069145777)
        self.assertAlmostEqual(scores["H", "M"], -3.923941994)
        self.assertAlmostEqual(scores["H", "N"], -0.900897195)
        self.assertAlmostEqual(scores["H", "P"], -2.047685997)
        self.assertAlmostEqual(scores["H", "Q"], -0.167730311)
        self.assertAlmostEqual(scores["H", "R"], -0.164976200)
        self.assertAlmostEqual(scores["H", "S"], -3.172194559)
        self.assertAlmostEqual(scores["H", "T"], -4.959888691)
        self.assertAlmostEqual(scores["H", "V"], -5.182742111)
        self.assertAlmostEqual(scores["H", "W"], -3.133037593)
        self.assertAlmostEqual(scores["H", "Y"], 0.264754960)
        self.assertAlmostEqual(scores["I", "A"], -3.420899738)
        self.assertAlmostEqual(scores["I", "C"], -5.095680501)
        self.assertAlmostEqual(scores["I", "D"], -5.818930812)
        self.assertAlmostEqual(scores["I", "E"], -4.754800475)
        self.assertAlmostEqual(scores["I", "F"], -3.386684023)
        self.assertAlmostEqual(scores["I", "G"], -6.307612452)
        self.assertAlmostEqual(scores["I", "H"], -4.990755347)
        self.assertAlmostEqual(scores["I", "I"], 3.868223896)
        self.assertAlmostEqual(scores["I", "K"], -4.651854173)
        self.assertAlmostEqual(scores["I", "L"], -1.908023091)
        self.assertAlmostEqual(scores["I", "M"], -0.545227873)
        self.assertAlmostEqual(scores["I", "N"], -3.303542788)
        self.assertAlmostEqual(scores["I", "P"], -6.120182987)
        self.assertAlmostEqual(scores["I", "Q"], -5.754800475)
        self.assertAlmostEqual(scores["I", "R"], -6.130557986)
        self.assertAlmostEqual(scores["I", "S"], -4.174302222)
        self.assertAlmostEqual(scores["I", "T"], -1.055105758)
        self.assertAlmostEqual(scores["I", "V"], 0.320300145)
        self.assertAlmostEqual(scores["I", "W"], -4.398179662)
        self.assertAlmostEqual(scores["I", "Y"], -5.459818728)
        self.assertAlmostEqual(scores["K", "A"], -4.571743998)
        self.assertAlmostEqual(scores["K", "C"], -5.076599760)
        self.assertAlmostEqual(scores["K", "D"], -4.799850071)
        self.assertAlmostEqual(scores["K", "E"], -1.462701239)
        self.assertAlmostEqual(scores["K", "F"], -5.952565782)
        self.assertAlmostEqual(scores["K", "G"], -4.703569210)
        self.assertAlmostEqual(scores["K", "H"], -3.386712104)
        self.assertAlmostEqual(scores["K", "I"], -4.651854173)
        self.assertAlmostEqual(scores["K", "K"], 3.944655396)
        self.assertAlmostEqual(scores["K", "L"], -7.315207104)
        self.assertAlmostEqual(scores["K", "M"], -2.848075227)
        self.assertAlmostEqual(scores["K", "N"], -1.358462628)
        self.assertAlmostEqual(scores["K", "P"], -6.101102246)
        self.assertAlmostEqual(scores["K", "Q"], -1.035280015)
        self.assertAlmostEqual(scores["K", "R"], 0.314787510)
        self.assertAlmostEqual(scores["K", "S"], -4.740183981)
        self.assertAlmostEqual(scores["K", "T"], -2.505510300)
        self.assertAlmostEqual(scores["K", "V"], -5.428803438)
        self.assertAlmostEqual(scores["K", "W"], -4.379098920)
        self.assertAlmostEqual(scores["K", "Y"], -4.440737986)
        self.assertAlmostEqual(scores["L", "A"], -4.084252669)
        self.assertAlmostEqual(scores["L", "C"], -5.174070931)
        self.assertAlmostEqual(scores["L", "D"], -5.897321242)
        self.assertAlmostEqual(scores["L", "E"], -6.418153406)
        self.assertAlmostEqual(scores["L", "F"], -1.349597236)
        self.assertAlmostEqual(scores["L", "G"], -5.801040381)
        self.assertAlmostEqual(scores["L", "H"], -5.069145777)
        self.assertAlmostEqual(scores["L", "I"], -1.908023091)
        self.assertAlmostEqual(scores["L", "K"], -7.315207104)
        self.assertAlmostEqual(scores["L", "L"], 2.931617632)
        self.assertAlmostEqual(scores["L", "M"], -1.058021128)
        self.assertAlmostEqual(scores["L", "N"], -5.118898812)
        self.assertAlmostEqual(scores["L", "P"], -2.154179298)
        self.assertAlmostEqual(scores["L", "Q"], -3.663265904)
        self.assertAlmostEqual(scores["L", "R"], -4.208948417)
        self.assertAlmostEqual(scores["L", "S"], -4.252692652)
        self.assertAlmostEqual(scores["L", "T"], -4.303421190)
        self.assertAlmostEqual(scores["L", "V"], -1.668293614)
        self.assertAlmostEqual(scores["L", "W"], -3.476570092)
        self.assertAlmostEqual(scores["L", "Y"], -5.538209158)
        self.assertAlmostEqual(scores["M", "A"], -3.202083293)
        self.assertAlmostEqual(scores["M", "C"], -4.028867149)
        self.assertAlmostEqual(scores["M", "D"], -4.752117460)
        self.assertAlmostEqual(scores["M", "E"], -5.272949623)
        self.assertAlmostEqual(scores["M", "F"], -3.904833171)
        self.assertAlmostEqual(scores["M", "G"], -3.655836599)
        self.assertAlmostEqual(scores["M", "H"], -3.923941994)
        self.assertAlmostEqual(scores["M", "I"], -0.545227873)
        self.assertAlmostEqual(scores["M", "K"], -2.848075227)
        self.assertAlmostEqual(scores["M", "L"], -1.058021128)
        self.assertAlmostEqual(scores["M", "M"], 4.916648279)
        self.assertAlmostEqual(scores["M", "N"], -4.558657530)
        self.assertAlmostEqual(scores["M", "P"], -5.053369635)
        self.assertAlmostEqual(scores["M", "Q"], -4.687987123)
        self.assertAlmostEqual(scores["M", "R"], -3.478782133)
        self.assertAlmostEqual(scores["M", "S"], -4.692451371)
        self.assertAlmostEqual(scores["M", "T"], -0.634655451)
        self.assertAlmostEqual(scores["M", "V"], -1.573715905)
        self.assertAlmostEqual(scores["M", "W"], -3.331366309)
        self.assertAlmostEqual(scores["M", "Y"], -4.393005375)
        self.assertAlmostEqual(scores["N", "A"], -4.375435706)
        self.assertAlmostEqual(scores["N", "C"], -4.465253968)
        self.assertAlmostEqual(scores["N", "D"], 0.133423815)
        self.assertAlmostEqual(scores["N", "E"], -4.709336443)
        self.assertAlmostEqual(scores["N", "F"], -4.341219991)
        self.assertAlmostEqual(scores["N", "G"], -2.869830997)
        self.assertAlmostEqual(scores["N", "H"], -0.900897195)
        self.assertAlmostEqual(scores["N", "I"], -3.303542788)
        self.assertAlmostEqual(scores["N", "K"], -1.358462628)
        self.assertAlmostEqual(scores["N", "L"], -5.118898812)
        self.assertAlmostEqual(scores["N", "M"], -4.558657530)
        self.assertAlmostEqual(scores["N", "N"], 4.496808747)
        self.assertAlmostEqual(scores["N", "P"], -5.489756455)
        self.assertAlmostEqual(scores["N", "Q"], -2.802445847)
        self.assertAlmostEqual(scores["N", "R"], -3.178203359)
        self.assertAlmostEqual(scores["N", "S"], -0.806910095)
        self.assertAlmostEqual(scores["N", "T"], -1.594604227)
        self.assertAlmostEqual(scores["N", "V"], -5.817457647)
        self.assertAlmostEqual(scores["N", "W"], -3.767753129)
        self.assertAlmostEqual(scores["N", "Y"], -3.829392195)
        self.assertAlmostEqual(scores["P", "A"], -2.207182798)
        self.assertAlmostEqual(scores["P", "C"], -3.959966073)
        self.assertAlmostEqual(scores["P", "D"], -5.683216384)
        self.assertAlmostEqual(scores["P", "E"], -6.204048548)
        self.assertAlmostEqual(scores["P", "F"], -5.835932096)
        self.assertAlmostEqual(scores["P", "G"], -6.171898024)
        self.assertAlmostEqual(scores["P", "H"], -2.047685997)
        self.assertAlmostEqual(scores["P", "I"], -6.120182987)
        self.assertAlmostEqual(scores["P", "K"], -6.101102246)
        self.assertAlmostEqual(scores["P", "L"], -2.154179298)
        self.assertAlmostEqual(scores["P", "M"], -5.053369635)
        self.assertAlmostEqual(scores["P", "N"], -5.489756455)
        self.assertAlmostEqual(scores["P", "P"], 4.121439949)
        self.assertAlmostEqual(scores["P", "Q"], -3.619086047)
        self.assertAlmostEqual(scores["P", "R"], -3.187488636)
        self.assertAlmostEqual(scores["P", "S"], -1.197285540)
        self.assertAlmostEqual(scores["P", "T"], -2.089316331)
        self.assertAlmostEqual(scores["P", "V"], -4.312169751)
        self.assertAlmostEqual(scores["P", "W"], -4.262465234)
        self.assertAlmostEqual(scores["P", "Y"], -5.324104300)
        self.assertAlmostEqual(scores["Q", "A"], -6.089727799)
        self.assertAlmostEqual(scores["Q", "C"], -4.594583561)
        self.assertAlmostEqual(scores["Q", "D"], -5.317833872)
        self.assertAlmostEqual(scores["Q", "E"], -1.379234416)
        self.assertAlmostEqual(scores["Q", "F"], -5.470549583)
        self.assertAlmostEqual(scores["Q", "G"], -5.806515511)
        self.assertAlmostEqual(scores["Q", "H"], -0.167730311)
        self.assertAlmostEqual(scores["Q", "I"], -5.754800475)
        self.assertAlmostEqual(scores["Q", "K"], -1.035280015)
        self.assertAlmostEqual(scores["Q", "L"], -3.663265904)
        self.assertAlmostEqual(scores["Q", "M"], -4.687987123)
        self.assertAlmostEqual(scores["Q", "N"], -2.802445847)
        self.assertAlmostEqual(scores["Q", "P"], -3.619086047)
        self.assertAlmostEqual(scores["Q", "Q"], 4.422253499)
        self.assertAlmostEqual(scores["Q", "R"], -0.074872194)
        self.assertAlmostEqual(scores["Q", "S"], -4.673205282)
        self.assertAlmostEqual(scores["Q", "T"], -4.723933819)
        self.assertAlmostEqual(scores["Q", "V"], -4.946787239)
        self.assertAlmostEqual(scores["Q", "W"], -3.897082721)
        self.assertAlmostEqual(scores["Q", "Y"], -3.958721787)
        self.assertAlmostEqual(scores["R", "A"], -4.465485311)
        self.assertAlmostEqual(scores["R", "C"], -1.800416071)
        self.assertAlmostEqual(scores["R", "D"], -4.108628883)
        self.assertAlmostEqual(scores["R", "E"], -3.407068625)
        self.assertAlmostEqual(scores["R", "F"], -5.846307095)
        self.assertAlmostEqual(scores["R", "G"], -1.481833305)
        self.assertAlmostEqual(scores["R", "H"], -0.164976200)
        self.assertAlmostEqual(scores["R", "I"], -6.130557986)
        self.assertAlmostEqual(scores["R", "K"], 0.314787510)
        self.assertAlmostEqual(scores["R", "L"], -4.208948417)
        self.assertAlmostEqual(scores["R", "M"], -3.478782133)
        self.assertAlmostEqual(scores["R", "N"], -3.178203359)
        self.assertAlmostEqual(scores["R", "P"], -3.187488636)
        self.assertAlmostEqual(scores["R", "Q"], -0.074872194)
        self.assertAlmostEqual(scores["R", "R"], 3.937295948)
        self.assertAlmostEqual(scores["R", "S"], -2.311997199)
        self.assertAlmostEqual(scores["R", "T"], -3.777763236)
        self.assertAlmostEqual(scores["R", "V"], -4.000616656)
        self.assertAlmostEqual(scores["R", "W"], -1.272840233)
        self.assertAlmostEqual(scores["R", "Y"], -5.334479299)
        self.assertAlmostEqual(scores["S", "A"], -1.286837125)
        self.assertAlmostEqual(scores["S", "C"], -2.429122807)
        self.assertAlmostEqual(scores["S", "D"], -3.737335619)
        self.assertAlmostEqual(scores["S", "E"], -4.258167782)
        self.assertAlmostEqual(scores["S", "F"], -2.568123236)
        self.assertAlmostEqual(scores["S", "G"], -1.489051665)
        self.assertAlmostEqual(scores["S", "H"], -3.172194559)
        self.assertAlmostEqual(scores["S", "I"], -4.174302222)
        self.assertAlmostEqual(scores["S", "K"], -4.740183981)
        self.assertAlmostEqual(scores["S", "L"], -4.252692652)
        self.assertAlmostEqual(scores["S", "M"], -4.692451371)
        self.assertAlmostEqual(scores["S", "N"], -0.806910095)
        self.assertAlmostEqual(scores["S", "P"], -1.197285540)
        self.assertAlmostEqual(scores["S", "Q"], -4.673205282)
        self.assertAlmostEqual(scores["S", "R"], -2.311997199)
        self.assertAlmostEqual(scores["S", "S"], 3.386624147)
        self.assertAlmostEqual(scores["S", "T"], -1.000477613)
        self.assertAlmostEqual(scores["S", "V"], -4.366288986)
        self.assertAlmostEqual(scores["S", "W"], -3.901546969)
        self.assertAlmostEqual(scores["S", "Y"], -2.963186035)
        self.assertAlmostEqual(scores["T", "A"], -0.238029989)
        self.assertAlmostEqual(scores["T", "C"], -5.064813845)
        self.assertAlmostEqual(scores["T", "D"], -3.466136061)
        self.assertAlmostEqual(scores["T", "E"], -5.308896320)
        self.assertAlmostEqual(scores["T", "F"], -4.355817367)
        self.assertAlmostEqual(scores["T", "G"], -4.691783295)
        self.assertAlmostEqual(scores["T", "H"], -4.959888691)
        self.assertAlmostEqual(scores["T", "I"], -1.055105758)
        self.assertAlmostEqual(scores["T", "K"], -2.505510300)
        self.assertAlmostEqual(scores["T", "L"], -4.303421190)
        self.assertAlmostEqual(scores["T", "M"], -0.634655451)
        self.assertAlmostEqual(scores["T", "N"], -1.594604227)
        self.assertAlmostEqual(scores["T", "P"], -2.089316331)
        self.assertAlmostEqual(scores["T", "Q"], -4.723933819)
        self.assertAlmostEqual(scores["T", "R"], -3.777763236)
        self.assertAlmostEqual(scores["T", "S"], -1.000477613)
        self.assertAlmostEqual(scores["T", "T"], 3.844754886)
        self.assertAlmostEqual(scores["T", "V"], -2.169090010)
        self.assertAlmostEqual(scores["T", "W"], -3.367313006)
        self.assertAlmostEqual(scores["T", "Y"], -5.428952072)
        self.assertAlmostEqual(scores["V", "A"], -0.875920908)
        self.assertAlmostEqual(scores["V", "C"], -4.287667265)
        self.assertAlmostEqual(scores["V", "D"], -4.010917576)
        self.assertAlmostEqual(scores["V", "E"], -4.946787239)
        self.assertAlmostEqual(scores["V", "F"], -2.841705193)
        self.assertAlmostEqual(scores["V", "G"], -2.412136375)
        self.assertAlmostEqual(scores["V", "H"], -5.182742111)
        self.assertAlmostEqual(scores["V", "I"], 0.320300145)
        self.assertAlmostEqual(scores["V", "K"], -5.428803438)
        self.assertAlmostEqual(scores["V", "L"], -1.668293614)
        self.assertAlmostEqual(scores["V", "M"], -1.573715905)
        self.assertAlmostEqual(scores["V", "N"], -5.817457647)
        self.assertAlmostEqual(scores["V", "P"], -4.312169751)
        self.assertAlmostEqual(scores["V", "Q"], -4.946787239)
        self.assertAlmostEqual(scores["V", "R"], -4.000616656)
        self.assertAlmostEqual(scores["V", "S"], -4.366288986)
        self.assertAlmostEqual(scores["V", "T"], -2.169090010)
        self.assertAlmostEqual(scores["V", "V"], 3.643217410)
        self.assertAlmostEqual(scores["V", "W"], -4.590166426)
        self.assertAlmostEqual(scores["V", "Y"], -5.651805492)
        self.assertAlmostEqual(scores["W", "A"], -3.733106986)
        self.assertAlmostEqual(scores["W", "C"], -2.237962748)
        self.assertAlmostEqual(scores["W", "D"], -3.961213059)
        self.assertAlmostEqual(scores["W", "E"], -4.482045222)
        self.assertAlmostEqual(scores["W", "F"], -4.113928770)
        self.assertAlmostEqual(scores["W", "G"], -1.864932198)
        self.assertAlmostEqual(scores["W", "H"], -3.133037593)
        self.assertAlmostEqual(scores["W", "I"], -4.398179662)
        self.assertAlmostEqual(scores["W", "K"], -4.379098920)
        self.assertAlmostEqual(scores["W", "L"], -3.476570092)
        self.assertAlmostEqual(scores["W", "M"], -3.331366309)
        self.assertAlmostEqual(scores["W", "N"], -3.767753129)
        self.assertAlmostEqual(scores["W", "P"], -4.262465234)
        self.assertAlmostEqual(scores["W", "Q"], -3.897082721)
        self.assertAlmostEqual(scores["W", "R"], -1.272840233)
        self.assertAlmostEqual(scores["W", "S"], -3.901546969)
        self.assertAlmostEqual(scores["W", "T"], -3.367313006)
        self.assertAlmostEqual(scores["W", "V"], -4.590166426)
        self.assertAlmostEqual(scores["W", "W"], 5.868929028)
        self.assertAlmostEqual(scores["W", "Y"], -3.602100974)
        self.assertAlmostEqual(scores["Y", "A"], -5.794746052)
        self.assertAlmostEqual(scores["Y", "C"], -0.977673719)
        self.assertAlmostEqual(scores["Y", "D"], -4.022852124)
        self.assertAlmostEqual(scores["Y", "E"], -5.543684288)
        self.assertAlmostEqual(scores["Y", "F"], -0.531711646)
        self.assertAlmostEqual(scores["Y", "G"], -5.511533764)
        self.assertAlmostEqual(scores["Y", "H"], 0.264754960)
        self.assertAlmostEqual(scores["Y", "I"], -5.459818728)
        self.assertAlmostEqual(scores["Y", "K"], -4.440737986)
        self.assertAlmostEqual(scores["Y", "L"], -5.538209158)
        self.assertAlmostEqual(scores["Y", "M"], -4.393005375)
        self.assertAlmostEqual(scores["Y", "N"], -3.829392195)
        self.assertAlmostEqual(scores["Y", "P"], -5.324104300)
        self.assertAlmostEqual(scores["Y", "Q"], -3.958721787)
        self.assertAlmostEqual(scores["Y", "R"], -5.334479299)
        self.assertAlmostEqual(scores["Y", "S"], -2.963186035)
        self.assertAlmostEqual(scores["Y", "T"], -5.428952072)
        self.assertAlmostEqual(scores["Y", "V"], -5.651805492)
        self.assertAlmostEqual(scores["Y", "W"], -3.602100974)
        self.assertAlmostEqual(scores["Y", "Y"], 4.795691579)

    def test_ident(self):
        """Test calculating the +6/-1 matrix as an approximation of BLOSUM62."""
        # Calculate the +6/-1 matrix as an approximation of the BLOSUM62 matrix.
        # Steven Henikoff & Jorja G. Henikoff:
        # Amino acid substitution matrices from protein blocks.
        # Proceedings of the National Academy of Sciences USA 89(2):
        # 10915-10919 (1992).
        from Bio.Data.IUPACData import protein_letters as alphabet

        m = substitution_matrices.load("BLOSUM62")
        self.assertEqual(alphabet, "ACDEFGHIKLMNPQRSTVWY")
        match_score = round(np.mean([m[c, c] for c in alphabet]))
        mismatch_score = round(
            np.mean([m[c1, c2] for c1 in alphabet for c2 in alphabet if c1 != c2])
        )
        self.assertAlmostEqual(match_score, 6.0)
        self.assertAlmostEqual(mismatch_score, -1.0)


class TestLoading(unittest.TestCase):
    def test_loading(self):
        """Confirm that all provided substitution matrices can be loaded."""
        names = substitution_matrices.load()
        for name in names:
            try:
                m = substitution_matrices.load(name)
            except Exception:
                self.fail(f"Failed to load substitution matrix '{name}'")

    def test_reading(self):
        """Confirm matrix reading works with filename or handle."""
        matrix_name = "BLOSUM62"
        test_path = os.path.dirname(__file__)
        parent_dir = os.path.dirname(test_path)
        sub_mx_dir = os.path.join(
            parent_dir, "Bio", "Align", "substitution_matrices", "data"
        )
        matrix_path = os.path.join(sub_mx_dir, matrix_name)

        fname_matrix = substitution_matrices.read(matrix_path)
        self.assertAlmostEqual(fname_matrix["A"]["A"], 4.0)
        self.assertEqual(len(fname_matrix), 24)
        self.assertEqual(len(fname_matrix[0]), 24)

        with open(matrix_path) as handle:
            handle_matrix = substitution_matrices.read(handle)
            self.assertFalse(handle.closed)
        self.assertTrue(handle.closed)
        self.assertAlmostEqual(handle_matrix["A"]["A"], 4.0)
        self.assertEqual(len(handle_matrix), 24)
        self.assertEqual(len(handle_matrix[0]), 24)


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