# Path: preimage/datasets/loader.py
# def load_amino_acids_and_descriptors(file_name=AminoAcidFile.blosum62_natural):
#     """Load amino acids and descriptors
# 
#     Parameters
#     ----------
#     file_name : string
#         file name of the amino acid matrix.
# 
#     Returns
#     -------
#     amino_acids: list
#         A list of amino acids (letters).
#     descriptors: array, shape = [n_amino_acids, n_amino_acids]
#         Substitution cost of each amino acid with all the other amino acids, where n_amino_acids is the number of
#         amino acids.
#     """
#     path_to_file = join(dirname(__file__), 'amino_acid_matrix', file_name)
#     with open(path_to_file, 'r') as data_file:
#         lines = data_file.readlines()
#     splitted_lines = numpy.array([line.split() for line in lines])
#     amino_acids = [str(letter) for letter in splitted_lines[:, 0]]
#     descriptors = numpy.array(splitted_lines[:, 1:], dtype=numpy.float)
#     return amino_acids, descriptors
# 
# Path: preimage/datasets/amino_acid_file.py
# class AminoAcidFile:
#     """Contain file name of amino acid property matrix from the literature.
# 
#     For more amino acid files see: http://graal.ift.ulaval.ca/bioinformatics/gs-kernel/.
# 
#     Attributes
#     ----------
#     blosum62_natural : string
#         file name of an amino acid matrix.
#     """
#     blosum62_natural = 'AA.blosum62.natural.dat'
# 
# Path: preimage/utils/position.py
# def compute_position_weights_matrix(max_position, sigma_position):
#     position_penalties = numpy.array([(i - j) for i in range(max_position) for j in range(max_position)],
#                                      dtype=numpy.float)
#     position_penalties = position_penalties.reshape(max_position, max_position)
#     position_penalties = numpy.square(position_penalties) / (-2 * (sigma_position ** 2))
#     return numpy.exp(position_penalties)
# 
# Path: preimage/utils/alphabet.py
# def transform_strings_to_integer_lists(Y, alphabet):
#     letter_to_int = get_n_gram_to_index(alphabet, 1)
#     n_examples = numpy.array(Y).shape[0]
#     max_length = numpy.max([len(y) for y in Y])
#     Y_int = numpy.zeros((n_examples, max_length), dtype=numpy.int8) - 1
#     for y_index, y in enumerate(Y):
#         for letter_index, letter in enumerate(y):
#             Y_int[y_index, letter_index] = letter_to_int[letter]
#     return Y_int


import numpy
from preimage.datasets.loader import load_amino_acids_and_descriptors
from preimage.kernels._generic_string import element_wise_generic_string_kernel, generic_string_kernel_with_sigma_c
from preimage.kernels._generic_string import element_wise_generic_string_kernel_with_sigma_c
from preimage.datasets.amino_acid_file import AminoAcidFile
from preimage.utils.position import compute_position_weights_matrix
from preimage.utils.alphabet import transform_strings_to_integer_lists
    Computes the similarity between two strings by comparing each of their l-gram of length 1 to n. Each l-gram
    comparison yields a score that depends on the similarity of their respective amino acids (letters) and a shifting
    contribution term that decays exponentially rapidly with the distance between the starting positions of the two
    substrings. The sigma_position parameter controls the shifting contribution term. The sigma_amino_acid parameter
    controls the amount of penalty incurred when the encoding vectors differ as measured by the squared Euclidean
    distance between these two vectors. The GS kernel outputs the sum of all the l-gram-comparison scores.

    Attributes
    ----------
    amino_acid_file_name : string
        Name of the file containing the amino acid substitution matrix.
    sigma_position : float
        Controls the penalty incurred when two n-grams are not sharing the same position.
    sigma_amino_acid : float
        Controls the penalty incurred when the encoding vectors of two amino acids differ.
    n : int
        N-gram length.
    is_normalized : bool
        True if the kernel should be normalized, False otherwise.

    Notes
    -----
    See http://graal.ift.ulaval.ca/bioinformatics/gs-kernel/ for the original code developed by Sebastien Giguere [1]_.

    References
    ----------
    .. [1] Sebastien Giguere, Mario Marchand, Francois Laviolette, Alexandre Drouin, and Jacques Corbeil. "Learning a
       peptide-protein binding affinity predictor with kernel ridge regression." BMC bioinformatics 14, no. 1 (2013):
       82.
    """

# Path: preimage/datasets/loader.py
# def load_amino_acids_and_descriptors(file_name=AminoAcidFile.blosum62_natural):
#     """Load amino acids and descriptors
# 
#     Parameters
#     ----------
#     file_name : string
#         file name of the amino acid matrix.
# 
#     Returns
#     -------
#     amino_acids: list
#         A list of amino acids (letters).
#     descriptors: array, shape = [n_amino_acids, n_amino_acids]
#         Substitution cost of each amino acid with all the other amino acids, where n_amino_acids is the number of
#         amino acids.
#     """
#     path_to_file = join(dirname(__file__), 'amino_acid_matrix', file_name)
#     with open(path_to_file, 'r') as data_file:
#         lines = data_file.readlines()
#     splitted_lines = numpy.array([line.split() for line in lines])
#     amino_acids = [str(letter) for letter in splitted_lines[:, 0]]
#     descriptors = numpy.array(splitted_lines[:, 1:], dtype=numpy.float)
#     return amino_acids, descriptors
# 
# Path: preimage/datasets/amino_acid_file.py
# class AminoAcidFile:
#     """Contain file name of amino acid property matrix from the literature.
# 
#     For more amino acid files see: http://graal.ift.ulaval.ca/bioinformatics/gs-kernel/.
# 
#     Attributes
#     ----------
#     blosum62_natural : string
#         file name of an amino acid matrix.
#     """
#     blosum62_natural = 'AA.blosum62.natural.dat'
# 
# Path: preimage/utils/position.py
# def compute_position_weights_matrix(max_position, sigma_position):
#     position_penalties = numpy.array([(i - j) for i in range(max_position) for j in range(max_position)],
#                                      dtype=numpy.float)
#     position_penalties = position_penalties.reshape(max_position, max_position)
#     position_penalties = numpy.square(position_penalties) / (-2 * (sigma_position ** 2))
#     return numpy.exp(position_penalties)
# 
# Path: preimage/utils/alphabet.py
# def transform_strings_to_integer_lists(Y, alphabet):
#     letter_to_int = get_n_gram_to_index(alphabet, 1)
#     n_examples = numpy.array(Y).shape[0]
#     max_length = numpy.max([len(y) for y in Y])
#     Y_int = numpy.zeros((n_examples, max_length), dtype=numpy.int8) - 1
#     for y_index, y in enumerate(Y):
#         for letter_index, letter in enumerate(y):
#             Y_int[y_index, letter_index] = letter_to_int[letter]
#     return Y_int


# Path: preimage/kernels/generic_string.py
import numpy
from preimage.datasets.loader import load_amino_acids_and_descriptors
from preimage.kernels._generic_string import element_wise_generic_string_kernel, generic_string_kernel_with_sigma_c
from preimage.kernels._generic_string import element_wise_generic_string_kernel_with_sigma_c
from preimage.datasets.amino_acid_file import AminoAcidFile
from preimage.utils.position import compute_position_weights_matrix
from preimage.utils.alphabet import transform_strings_to_integer_lists

    Computes the similarity between two strings by comparing each of their l-gram of length 1 to n. Each l-gram
    comparison yields a score that depends on the similarity of their respective amino acids (letters) and a shifting
    contribution term that decays exponentially rapidly with the distance between the starting positions of the two
    substrings. The sigma_position parameter controls the shifting contribution term. The sigma_amino_acid parameter
    controls the amount of penalty incurred when the encoding vectors differ as measured by the squared Euclidean
    distance between these two vectors. The GS kernel outputs the sum of all the l-gram-comparison scores.

    Attributes
    ----------
    amino_acid_file_name : string
        Name of the file containing the amino acid substitution matrix.
    sigma_position : float
        Controls the penalty incurred when two n-grams are not sharing the same position.
    sigma_amino_acid : float
        Controls the penalty incurred when the encoding vectors of two amino acids differ.
    n : int
        N-gram length.
    is_normalized : bool
        True if the kernel should be normalized, False otherwise.

    Notes
    -----
    See http://graal.ift.ulaval.ca/bioinformatics/gs-kernel/ for the original code developed by Sebastien Giguere [1]_.

    References
    ----------
    .. [1] Sebastien Giguere, Mario Marchand, Francois Laviolette, Alexandre Drouin, and Jacques Corbeil. "Learning a
       peptide-protein binding affinity predictor with kernel ridge regression." BMC bioinformatics 14, no. 1 (2013):
       82.
    """

    def __init__(self, amino_acid_file_name=AminoAcidFile.blosum62_natural, sigma_position=1.0, sigma_amino_acid=1.0,