# Path: enrich2/constants.py
# WILD_TYPE_VARIANT = "_wt"
# 
# Path: enrich2/variant.py
# DEFAULT_MAX_MUTATIONS = 10
# def valid_variant(s, is_coding=True):
# def hgvs2single(s):
# def single2hgvs(s):
# def get_variant_type(variant):
# def mutation_count(variant):
# def has_indel(variant):
# def has_unresolvable(variant):
# def protein_variant(variant):
#     def __init__(self):
#     def configure(self, cfg):
#     def serialize(self):
#     def is_coding(self):
#     def has_wt_sequence(self):
#     def align_variant(self, variant_dna):
#     def count_variant(self, variant_dna, include_indels=True):
#     def count_synonymous(self):
#     def report_filtered_variant(self, variant, count):
# class VariantSeqLib(SeqLib):
# 
# Path: enrich2/barcodemap.py
# class BarcodeMap(dict):
#     def __init__(self, mapfile, is_variant=False):
# 
# Path: enrich2/constants.py
# AA_CODES = {
#     "Ala": "A",
#     "A": "Ala",
#     "Arg": "R",
#     "R": "Arg",
#     "Asn": "N",
#     "N": "Asn",
#     "Asp": "D",
#     "D": "Asp",
#     "Cys": "C",
#     "C": "Cys",
#     "Glu": "E",
#     "E": "Glu",
#     "Gln": "Q",
#     "Q": "Gln",
#     "Gly": "G",
#     "G": "Gly",
#     "His": "H",
#     "H": "His",
#     "Ile": "I",
#     "I": "Ile",
#     "Leu": "L",
#     "L": "Leu",
#     "Lys": "K",
#     "K": "Lys",
#     "Met": "M",
#     "M": "Met",
#     "Phe": "F",
#     "F": "Phe",
#     "Pro": "P",
#     "P": "Pro",
#     "Ser": "S",
#     "S": "Ser",
#     "Thr": "T",
#     "T": "Thr",
#     "Trp": "W",
#     "W": "Trp",
#     "Tyr": "Y",
#     "Y": "Tyr",
#     "Val": "V",
#     "V": "Val",
#     "Ter": "*",
#     "*": "Ter",
#     "???": "?",
#     "?": "???",
# }
# 
# Path: enrich2/storemanager.py
# ELEMENT_LABELS = ["barcodes", "identifiers", "variants", "synonymous"]
# 
# Path: enrich2/sfmap.py
# AA_LIST = [
#     "H",
#     "K",
#     "R",  # (+)
#     "D",
#     "E",  # (-)
#     "C",
#     "M",
#     "N",
#     "Q",
#     "S",
#     "T",  # Polar-neutral
#     "A",
#     "I",
#     "L",
#     "V",  # Non-polar
#     "F",
#     "W",
#     "Y",  # Aromatic
#     "G",
#     "P",  # Unique
#     "*",
# ]
# 
# NT_LIST = ["A", "C", "G", "T"]


import pandas as pd
import numpy as np
import logging
import collections
from .constants import WILD_TYPE_VARIANT
from .variant import mutation_count, re_protein, re_coding, re_noncoding
from .barcodemap import re_barcode, re_identifier
from .constants import AA_CODES
from .storemanager import ELEMENT_LABELS
from .sfmap import AA_LIST, NT_LIST


def single_mutations_to_tuples(index):
    """
    Return a list of SingleMut namedtuples for each single mutation in the
    *index*. The type of index (noncoding DNA, coding DNA, or protein) is
    automatically detected.

    Position value in the tuple is stored as an integer.

    If the *index* is a protein index, the amino acids are referred to by
    single-letter codes not three-letter codes.

    *index* is the index to convert to SingleMut tuples.

    Raises a ValueError if non-single mutations are included in *index*.

    Raises a ValueError if one of the *index* entries cannot be parsed.

    Raises an IndexError if the *index* is empty.
    """
    if any(mutation_count(x) != 1 for x in index):
        raise ValueError(
            "Non-single mutations cannot be converted into " "SingleMut tuples."
        )

    # identify the type of index
    try:
        if re_noncoding.match(index[0]):
            is_protein = False

# Path: enrich2/constants.py
# WILD_TYPE_VARIANT = "_wt"
# 
# Path: enrich2/variant.py
# DEFAULT_MAX_MUTATIONS = 10
# def valid_variant(s, is_coding=True):
# def hgvs2single(s):
# def single2hgvs(s):
# def get_variant_type(variant):
# def mutation_count(variant):
# def has_indel(variant):
# def has_unresolvable(variant):
# def protein_variant(variant):
#     def __init__(self):
#     def configure(self, cfg):
#     def serialize(self):
#     def is_coding(self):
#     def has_wt_sequence(self):
#     def align_variant(self, variant_dna):
#     def count_variant(self, variant_dna, include_indels=True):
#     def count_synonymous(self):
#     def report_filtered_variant(self, variant, count):
# class VariantSeqLib(SeqLib):
# 
# Path: enrich2/barcodemap.py
# class BarcodeMap(dict):
#     def __init__(self, mapfile, is_variant=False):
# 
# Path: enrich2/constants.py
# AA_CODES = {
#     "Ala": "A",
#     "A": "Ala",
#     "Arg": "R",
#     "R": "Arg",
#     "Asn": "N",
#     "N": "Asn",
#     "Asp": "D",
#     "D": "Asp",
#     "Cys": "C",
#     "C": "Cys",
#     "Glu": "E",
#     "E": "Glu",
#     "Gln": "Q",
#     "Q": "Gln",
#     "Gly": "G",
#     "G": "Gly",
#     "His": "H",
#     "H": "His",
#     "Ile": "I",
#     "I": "Ile",
#     "Leu": "L",
#     "L": "Leu",
#     "Lys": "K",
#     "K": "Lys",
#     "Met": "M",
#     "M": "Met",
#     "Phe": "F",
#     "F": "Phe",
#     "Pro": "P",
#     "P": "Pro",
#     "Ser": "S",
#     "S": "Ser",
#     "Thr": "T",
#     "T": "Thr",
#     "Trp": "W",
#     "W": "Trp",
#     "Tyr": "Y",
#     "Y": "Tyr",
#     "Val": "V",
#     "V": "Val",
#     "Ter": "*",
#     "*": "Ter",
#     "???": "?",
#     "?": "???",
# }
# 
# Path: enrich2/storemanager.py
# ELEMENT_LABELS = ["barcodes", "identifiers", "variants", "synonymous"]
# 
# Path: enrich2/sfmap.py
# AA_LIST = [
#     "H",
#     "K",
#     "R",  # (+)
#     "D",
#     "E",  # (-)
#     "C",
#     "M",
#     "N",
#     "Q",
#     "S",
#     "T",  # Polar-neutral
#     "A",
#     "I",
#     "L",
#     "V",  # Non-polar
#     "F",
#     "W",
#     "Y",  # Aromatic
#     "G",
#     "P",  # Unique
#     "*",
# ]
# 
# NT_LIST = ["A", "C", "G", "T"]


# Path: enrich2/dataframe.py
import pandas as pd
import numpy as np
import logging
import collections
from .constants import WILD_TYPE_VARIANT
from .variant import mutation_count, re_protein, re_coding, re_noncoding
from .barcodemap import re_barcode, re_identifier
from .constants import AA_CODES
from .storemanager import ELEMENT_LABELS
from .sfmap import AA_LIST, NT_LIST



def single_mutations_to_tuples(index):
    """
    Return a list of SingleMut namedtuples for each single mutation in the
    *index*. The type of index (noncoding DNA, coding DNA, or protein) is
    automatically detected.

    Position value in the tuple is stored as an integer.

    If the *index* is a protein index, the amino acids are referred to by
    single-letter codes not three-letter codes.

    *index* is the index to convert to SingleMut tuples.

    Raises a ValueError if non-single mutations are included in *index*.

    Raises a ValueError if one of the *index* entries cannot be parsed.

    Raises an IndexError if the *index* is empty.
    """
    if any(mutation_count(x) != 1 for x in index):
        raise ValueError(
            "Non-single mutations cannot be converted into " "SingleMut tuples."
        )

    # identify the type of index
    try:
        if re_noncoding.match(index[0]):
            is_protein = False

            expression = re_noncoding