<commit_before># Copyright (c) 2015. Mount Sinai School of Medicine
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function, division, absolute_import

from memoized_property import memoized_property


class MutationEffect(object):
    """
    Base class for mutation effects.
    """

    def __init__(self, variant):
        self.variant = variant

    def __str__(self):
        return "%s(%s)" % (self.__class__.__name__, self.variant)

    def __repr__(self):
        return str(self)

    def __lt__(self, other):
        """
        Effects are ordered by their associated variants, which have
        comparison implement in terms of their chromosomal locations.
        """
        return self.variant < other.variant

    @property
    def short_description(self):
        raise ValueError(
            "Property short_description not implemented for %s" % (
                self.__class__.__name__,))

    transcript = None
    gene = None

    @memoized_property
    def original_protein_sequence(self):
        """Amino acid sequence of a coding transcript (without the nucleotide
        variant/mutation)
        """
        if self.transcript:
            return self.transcript.protein_sequence
        else:
            return None

    @memoized_property
    def gene_name(self):
        if self.gene:
            return self.gene.name
        else:
            return None

    @memoized_property
    def gene_id(self):
        if self.gene:
            return self.gene.id
        else:
            return None

    @memoized_property
    def transcript_name(self):
        if self.transcript:
            return self.transcript.name
        else:
            return None

    @memoized_property
    def transcript_id(self):
        if self.transcript:
            return self.transcript.id
        else:
            return None

    # It's convenient to have a property which tells us:
    # 1) is this a variant effect overlapping a transcript?
    # 2) does that transcript have a coding sequence?
    # 3) does the variant affect the coding sequence?
    modifies_coding_sequence = False

    # Additionally:
    # 4) Does the change to the coding sequence result in a change to the
    # protein sequence?
    modifies_protein_sequence = False

    mutant_protein_sequence = None

    # which residues in the mutant protein sequence are different from
    # the original?
    aa_mutation_start_offset = None
    aa_mutation_end_offset = None


class Intergenic(MutationEffect):
    """Variant has unknown effect if it occurs between genes"""
    short_description = "intergenic"


class Intragenic(MutationEffect):
    """Variant within boundaries of a gene but does not overlap
    introns or exons of any transcript. This seems very peculiar but
    apparently does happen sometimes, maybe some genes have two distinct sets
    of exons which are never simultaneously expressed?
    """

    def __init__(self, variant, gene):
        MutationEffect.__init__(self, variant)
        self.gene = gene

class TranscriptMutationEffect(Intragenic):
    def __init__(self, variant, transcript):
        Intragenic.__init__(self, variant, gene=transcript.gene)
        self.transcript = transcript

    def __str__(self):
        return "%s(variant=%s, transcript_name=%s, transcript_id=%s)" % (
            self.__class__.__name__,
            self.variant.short_description,
            self.transcript.name,
            self.transcript.id)


class Failure(TranscriptMutationEffect):
    """Special placeholder effect for when we want to suppress errors but still
    need to create a non-empty list of effects for each variant.
    """

class NoncodingTranscript(TranscriptMutationEffect):
    """
    Any mutation to a transcript with a non-coding biotype
    """<commit_msg>add a default description to all effects and fix #129<commit_after># Copyright (c) 2015. Mount Sinai School of Medicine
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function, division, absolute_import

from memoized_property import memoized_property


class MutationEffect(object):
    """
    Base class for mutation effects.
    """

    def __init__(self, variant):
        self.variant = variant

    def __str__(self):
        return "%s(%s)" % (self.__class__.__name__, self.variant)

    def __repr__(self):
        return str(self)

    def __lt__(self, other):
        """
        Effects are ordered by their associated variants, which have
        comparison implement in terms of their chromosomal locations.
        """
        return self.variant < other.variant

    @property
    def short_description(self):
        """
        A short but human-readable description of the effect.
        Defaults to class name for most of the non-coding effects,
        but is more informative for coding ones.
        """
        return self.__class__.__name__.lower()

    transcript = None
    gene = None

    @memoized_property
    def original_protein_sequence(self):
        """Amino acid sequence of a coding transcript (without the nucleotide
        variant/mutation)
        """
        if self.transcript:
            return self.transcript.protein_sequence
        else:
            return None

    @memoized_property
    def gene_name(self):
        if self.gene:
            return self.gene.name
        else:
            return None

    @memoized_property
    def gene_id(self):
        if self.gene:
            return self.gene.id
        else:
            return None

    @memoized_property
    def transcript_name(self):
        if self.transcript:
            return self.transcript.name
        else:
            return None

    @memoized_property
    def transcript_id(self):
        if self.transcript:
            return self.transcript.id
        else:
            return None

    # It's convenient to have a property which tells us:
    # 1) is this a variant effect overlapping a transcript?
    # 2) does that transcript have a coding sequence?
    # 3) does the variant affect the coding sequence?
    modifies_coding_sequence = False

    # Additionally:
    # 4) Does the change to the coding sequence result in a change to the
    # protein sequence?
    modifies_protein_sequence = False

    mutant_protein_sequence = None

    # which residues in the mutant protein sequence are different from
    # the original?
    aa_mutation_start_offset = None
    aa_mutation_end_offset = None


class Intergenic(MutationEffect):
    """Variant has unknown effect if it occurs between genes"""
    short_description = "intergenic"


class Intragenic(MutationEffect):
    """Variant within boundaries of a gene but does not overlap
    introns or exons of any transcript. This seems very peculiar but
    apparently does happen sometimes, maybe some genes have two distinct sets
    of exons which are never simultaneously expressed?
    """
    short_description = "intragenic"

    def __init__(self, variant, gene):
        MutationEffect.__init__(self, variant)
        self.gene = gene

class TranscriptMutationEffect(Intragenic):
    def __init__(self, variant, transcript):
        Intragenic.__init__(self, variant, gene=transcript.gene)
        self.transcript = transcript

    def __str__(self):
        return "%s(variant=%s, transcript_name=%s, transcript_id=%s)" % (
            self.__class__.__name__,
            self.variant.short_description,
            self.transcript.name,
            self.transcript.id)


class Failure(TranscriptMutationEffect):
    """Special placeholder effect for when we want to suppress errors but still
    need to create a non-empty list of effects for each variant.
    """

class NoncodingTranscript(TranscriptMutationEffect):
    """
    Any mutation to a transcript with a non-coding biotype
    """
{'fraction_non_alphanumeric': 0.0681586978636826, 'fraction_numerical': 0.003051881993896236, 'mean_word_length': 2.723905723905724, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1312105', 'n_tokens_mistral': 2391, 'n_tokens_neox': 2206, 'n_words': 851}