diff --git a/src/game/genetics/amino-acid.hpp b/src/game/genetics/amino-acid.hpp new file mode 100644 index 0000000..123e321 --- /dev/null +++ b/src/game/genetics/amino-acid.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GENETICS_AMINO_ACID_HPP +#define ANTKEEPER_GENETICS_AMINO_ACID_HPP + +#include + +namespace genetics { +namespace amino_acid { + +/** + * Scores two amino acids using a substitution matrix. + * + * @param a IUPAC amino acid code of first amino acid. + * @param b IUPAC amino acid code of second amino acid. + * @param matrix Substitution matrix. + * @return Score of the two amino acids. + */ +template +typename std::remove_all_extents::type score(char a, char b, const Matrix& matrix); + +template +typename std::remove_all_extents::type score(char a, char b, const Matrix& matrix) +{ + int i = (a < 'A' || a > 'Z') ? ((a == '*') ? 26 : -1) : a - 'A'; + int j = (b < 'A' || b > 'Z') ? ((b == '*') ? 26 : -1) : b - 'A'; + + if (i < 0 || j < 0) + return 0; + + return matrix[i][j]; +} + +} // namspace amino_acid +} // namespace genetics + +#endif // ANTKEEPER_GENETICS_AMINO_ACID_HPP diff --git a/src/game/genetics/genetics.hpp b/src/game/genetics/genetics.hpp index e4a7a78..3f84fea 100644 --- a/src/game/genetics/genetics.hpp +++ b/src/game/genetics/genetics.hpp @@ -20,9 +20,12 @@ #ifndef ANTKEEPER_GENETICS_HPP #define ANTKEEPER_GENETICS_HPP +#include "amino-acid.hpp" #include "base.hpp" #include "codon.hpp" +#include "matrix.hpp" #include "protein.hpp" #include "sequence.hpp" +#include "translation-table.hpp" #endif // ANTKEEPER_GENETICS_HPP diff --git a/src/game/genetics/matrix.hpp b/src/game/genetics/matrix.hpp new file mode 100644 index 0000000..933cdcf --- /dev/null +++ b/src/game/genetics/matrix.hpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GENETICS_MATRIX_HPP +#define ANTKEEPER_GENETICS_MATRIX_HPP + +namespace genetics { +namespace matrix { + +/** + * BLOSUM62 substitution matrix. + * + * @see ftp://ftp.ncbi.nih.gov/blast/matrices/ + */ +template +constexpr T blosum62[27][27] = +{ + // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z * + { 4, -2, 0, -2, -1, -2, 0, -2, -1, 0, -1, -1, -1, -2, 0, -1, -1, -1, 1, 0, 0, 0, -3, 0, -2, -1, -4 }, // A + { -2, 4, -3, 4, 1, -3, -1, 0, -3, 0, 0, -4, -3, 3, 0, -2, 0, -1, 0, -1, 0, -3, -4, -1, -3, 1, -4 }, // B + { 0, -3, 9, -3, -4, -2, -3, -3, -1, 0, -3, -1, -1, -3, 0, -3, -3, -3, -1, -1, 0, -1, -2, -2, -2, -3, -4 }, // C + { -2, 4, -3, 6, 2, -3, -1, -1, -3, 0, -1, -4, -3, 1, 0, -1, 0, -2, 0, -1, 0, -3, -4, -1, -3, 1, -4 }, // D + { -1, 1, -4, 2, 5, -3, -2, 0, -3, 0, 1, -3, -2, 0, 0, -1, 2, 0, 0, -1, 0, -2, -3, -1, -2, 4, -4 }, // E + { -2, -3, -2, -3, -3, 6, -3, -1, 0, 0, -3, 0, 0, -3, 0, -4, -3, -3, -2, -2, 0, -1, 1, -1, 3, -3, -4 }, // F + { 0, -1, -3, -1, -2, -3, 6, -2, -4, 0, -2, -4, -3, 0, 0, -2, -2, -2, 0, -2, 0, -3, -2, -1, -3, -2, -4 }, // G + { -2, 0, -3, -1, 0, -1, -2, 8, -3, 0, -1, -3, -2, 1, 0, -2, 0, 0, -1, -2, 0, -3, -2, -1, 2, 0, -4 }, // H + { -1, -3, -1, -3, -3, 0, -4, -3, 4, 0, -3, 2, 1, -3, 0, -3, -3, -3, -2, -1, 0, 3, -3, -1, -1, -3, -4 }, // I + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // J + { -1, 0, -3, -1, 1, -3, -2, -1, -3, 0, 5, -2, -1, 0, 0, -1, 1, 2, 0, -1, 0, -2, -3, -1, -2, 1, -4 }, // K + { -1, -4, -1, -4, -3, 0, -4, -3, 2, 0, -2, 4, 2, -3, 0, -3, -2, -2, -2, -1, 0, 1, -2, -1, -1, -3, -4 }, // L + { -1, -3, -1, -3, -2, 0, -3, -2, 1, 0, -1, 2, 5, -2, 0, -2, 0, -1, -1, -1, 0, 1, -1, -1, -1, -1, -4 }, // M + { -2, 3, -3, 1, 0, -3, 0, 1, -3, 0, 0, -3, -2, 6, 0, -2, 0, 0, 1, 0, 0, -3, -4, -1, -2, 0, -4 }, // N + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // O + { -1, -2, -3, -1, -1, -4, -2, -2, -3, 0, -1, -3, -2, -2, 0, 7, -1, -2, -1, -1, 0, -2, -4, -2, -3, -1, -4 }, // P + { -1, 0, -3, 0, 2, -3, -2, 0, -3, 0, 1, -2, 0, 0, 0, -1, 5, 1, 0, -1, 0, -2, -2, -1, -1, 3, -4 }, // Q + { -1, -1, -3, -2, 0, -3, -2, 0, -3, 0, 2, -2, -1, 0, 0, -2, 1, 5, -1, -1, 0, -3, -3, -1, -2, 0, -4 }, // R + { 1, 0, -1, 0, 0, -2, 0, -1, -2, 0, 0, -2, -1, 1, 0, -1, 0, -1, 4, 1, 0, -2, -3, 0, -2, 0, -4 }, // S + { 0, -1, -1, -1, -1, -2, -2, -2, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1, 1, 5, 0, 0, -2, 0, -2, -1, -4 }, // T + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // U + { 0, -3, -1, -3, -2, -1, -3, -3, 3, 0, -2, 1, 1, -3, 0, -2, -2, -3, -2, 0, 0, 4, -3, -1, -1, -2, -4 }, // V + { -3, -4, -2, -4, -3, 1, -2, -2, -3, 0, -3, -2, -1, -4, 0, -4, -2, -3, -3, -2, 0, -3, 11, -2, 2, -3, -4 }, // W + { 0, -1, -2, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 0, -2, -1, -1, 0, 0, 0, -1, -2, -1, -1, -1, -4 }, // X + { -2, -3, -2, -3, -2, 3, -3, 2, -1, 0, -2, -1, -1, -2, 0, -3, -1, -2, -2, -2, 0, -1, 2, -1, 7, -2, -4 }, // Y + { -1, 1, -3, 1, 4, -3, -2, 0, -3, 0, 1, -3, -1, 0, 0, -1, 3, 0, 0, -1, 0, -2, -3, -1, -2, 4, -4 }, // Z + { -4, -4, -4, -4, -4, -4, -4, -4, -4, 0, -4, -4, -4, -4, 0, -4, -4, -4, -4, -4, 0, -4, -4, -4, -4, -4, 1 } // * +}; + +/** + * BLOSUM80 substitution matrix. + * + * @see ftp://ftp.ncbi.nih.gov/blast/matrices/ + */ +template +constexpr T blosum80[27][27] = +{ + // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z * + { 7, -3, -1, -3, -2, -4, 0, -3, -3, 0, -1, -3, -2, -3, 0, -1, -2, -3, 2, 0, 0, -1, -5, -1, -4, -2, -8 }, // A + { -3, 6, -6, 6, 1, -6, -2, -1, -6, 0, -1, -7, -5, 5, 0, -4, -1, -2, 0, -1, 0, -6, -8, -3, -5, 0, -8 }, // B + { -1, -6, 13, -7, -7, -4, -6, -7, -2, 0, -6, -3, -3, -5, 0, -6, -5, -6, -2, -2, 0, -2, -5, -4, -5, -7, -8 }, // C + { -3, 6, -7, 10, 2, -6, -3, -2, -7, 0, -2, -7, -6, 2, 0, -3, -1, -3, -1, -2, 0, -6, -8, -3, -6, 1, -8 }, // D + { -2, 1, -7, 2, 8, -6, -4, 0, -6, 0, 1, -6, -4, -1, 0, -2, 3, -1, -1, -2, 0, -4, -6, -2, -5, 6, -8 }, // E + { -4, -6, -4, -6, -6, 10, -6, -2, -1, 0, -5, 0, 0, -6, 0, -6, -5, -5, -4, -4, 0, -2, 0, -3, 4, -6, -8 }, // F + { 0, -2, -6, -3, -4, -6, 9, -4, -7, 0, -3, -7, -5, -1, 0, -5, -4, -4, -1, -3, 0, -6, -6, -3, -6, -4, -8 }, // G + { -3, -1, -7, -2, 0, -2, -4, 12, -6, 0, -1, -5, -4, 1, 0, -4, 1, 0, -2, -3, 0, -5, -4, -2, 3, 0, -8 }, // H + { -3, -6, -2, -7, -6, -1, -7, -6, 7, 0, -5, 2, 2, -6, 0, -5, -5, -5, -4, -2, 0, 4, -5, -2, -3, -6, -8 }, // I + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // J + { -1, -1, -6, -2, 1, -5, -3, -1, -5, 0, 8, -4, -3, 0, 0, -2, 2, 3, -1, -1, 0, -4, -6, -2, -4, 1, -8 }, // K + { -3, -7, -3, -7, -6, 0, -7, -5, 2, 0, -4, 6, 3, -6, 0, -5, -4, -4, -4, -3, 0, 1, -4, -2, -2, -5, -8 }, // L + { -2, -5, -3, -6, -4, 0, -5, -4, 2, 0, -3, 3, 9, -4, 0, -4, -1, -3, -3, -1, 0, 1, -3, -2, -3, -3, -8 }, // M + { -3, 5, -5, 2, -1, -6, -1, 1, -6, 0, 0, -6, -4, 9, 0, -4, 0, -1, 1, 0, 0, -5, -7, -2, -4, -1, -8 }, // N + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // O + { -1, -4, -6, -3, -2, -6, -5, -4, -5, 0, -2, -5, -4, -4, 0, 12, -3, -3, -2, -3, 0, -4, -7, -3, -6, -2, -8 }, // P + { -2, -1, -5, -1, 3, -5, -4, 1, -5, 0, 2, -4, -1, 0, 0, -3, 9, 1, -1, -1, 0, -4, -4, -2, -3, 5, -8 }, // Q + { -3, -2, -6, -3, -1, -5, -4, 0, -5, 0, 3, -4, -3, -1, 0, -3, 1, 9, -2, -2, 0, -4, -5, -2, -4, 0, -8 }, // R + { 2, 0, -2, -1, -1, -4, -1, -2, -4, 0, -1, -4, -3, 1, 0, -2, -1, -2, 7, 2, 0, -3, -6, -1, -3, -1, -8 }, // S + { 0, -1, -2, -2, -2, -4, -3, -3, -2, 0, -1, -3, -1, 0, 0, -3, -1, -2, 2, 8, 0, 0, -5, -1, -3, -2, -8 }, // T + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // U + { -1, -6, -2, -6, -4, -2, -6, -5, 4, 0, -4, 1, 1, -5, 0, -4, -4, -4, -3, 0, 0, 7, -5, -2, -3, -4, -8 }, // V + { -5, -8, -5, -8, -6, 0, -6, -4, -5, 0, -6, -4, -3, -7, 0, -7, -4, -5, -6, -5, 0, -5, 16, -5, 3, -5, -8 }, // W + { -1, -3, -4, -3, -2, -3, -3, -2, -2, 0, -2, -2, -2, -2, 0, -3, -2, -2, -1, -1, 0, -2, -5, -2, -3, -1, -8 }, // X + { -4, -5, -5, -6, -5, 4, -6, 3, -3, 0, -4, -2, -3, -4, 0, -6, -3, -4, -3, -3, 0, -3, 3, -3, 11, -4, -8 }, // Y + { -2, 0, -7, 1, 6, -6, -4, 0, -6, 0, 1, -5, -3, -1, 0, -2, 5, 0, -1, -2, 0, -4, -5, -1, -4, 6, -8 }, // Z + { -8, -8, -8, -8, -8, -8, -8, -8, -8, 0, -8, -8, -8, -8, 0, -8, -8, -8, -8, -8, 0, -8, -8, -8, -8, -8, 1 } // * +}; + +} // namspace matrix +} // namespace genetics + +#endif // ANTKEEPER_GENETICS_MATRIX_HPP diff --git a/src/game/genetics/protein.hpp b/src/game/genetics/protein.hpp index eab430c..4e3ab38 100644 --- a/src/game/genetics/protein.hpp +++ b/src/game/genetics/protein.hpp @@ -20,10 +20,31 @@ #ifndef ANTKEEPER_GENETICS_PROTEIN_HPP #define ANTKEEPER_GENETICS_PROTEIN_HPP +#include "amino-acid.hpp" +#include + namespace genetics { namespace protein { +/** + * Scores two proteins using a substitution matrix. + * + * @param first1,last1 Sequence of IUPAC amino acid codes which constitute the first protein. + * @param first2,last2 Sequence of IUPAC amino acid codes which constitute the second protein. + * @param matrix Substitution matrix. + * @return Score of the two proteins. + */ +template +typename std::remove_all_extents::type score(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2, const Matrix& matrix); +template +typename std::remove_all_extents::type score(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2, const Matrix& matrix) +{ + typename std::remove_all_extents::type result = 0; + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + result += amino_acid::score(*first1, *first2, matrix); + return result; +} } // namespace protein } // namespace genetics