# Path: scripts/seq_classes.py
# def locus(self,pos):
#     loci = [x for x in self.seq if x.pos==pos]
#     return loci[0]
# 
# class locus(object):
#     """ A base which has the following characteristics 
#         Atrributes :
#             Chr : chromosome
#             pos : position on chromosome base 0
#             counts : a dictionary of { A : the number of As
#             T : the number of Ts
#             C : the number of Cs
#             G : the number of Gs
#             - : the number of of deletions    
#             }
#             add consensus.
#             add concat_pos
#         methods : 
#             update : update counts
#             calc_freqs :  calculate the frequency of each base
#             consensus : caculate the consensus sequence as this position 
#     """
#     def __init__(self,pos):
#         """
#         return a base object with chr and pos and starting counts of 0
#         Posisition is base 0 because this is python and I want to keep everything 
#         easy to remember. If it came from python it is base 0.
#         """
#         self.pos = pos
#         # self.alleles = {'A':allele("A"),
#         #                 'T':allele("T"),
#         #                 'C':allele("C"),
#         #                 'G':allele("G"),
#         #                 '-':allele("-")}
#         self.alleles = {}
#         self.coverage = 0
#         self.concat_pos = None
#         self.consensus = ''
# 
#     def update(self,base):
#         self.coverage = self.coverage+1
# 
#         if base in self.alleles.keys():
#             self.alleles[base].count+=1
#             
#         else:
#             self.alleles.update({base:allele(base)})
#             self.alleles[base].count+=1
# 
#         self.calc_freqs()
#         self.consensus = self.calc_consensus()
#     def calc_freqs(self):
#         for base in self.alleles.keys():
#             self.alleles[base].freq = self.alleles[base].count/self.coverage
#             
#     def calc_consensus(self,cutoff=None):
#         if self.coverage==0:
#             return '-'
#         else:
#             self.calc_freqs()
#             v=[y.freq for y  in self.alleles.values()] #values
#             k=list(self.alleles.keys()) # key
#             # check for cutoff method
#             if cutoff ==None:
#                 # Return the most common base
#                 return k[v.index(max(v))]
#             
#                     
#             else:
#                 # return the base that is above the cutoff
#                 if type(cutoff)!=float or (cutoff>1 or cutoff<0.5):
#                     raise ValueError('cutoff must be a float in [0.5,1.0] or nothing')
#                 indexes = [index for index, value in enumerate(v) if value > cutoff]
#                 if len(indexes)==1:
#                     consensus = k[indexes[0]]
#                 else:
#                     consensus = "N"
#                 return consensus
# 
#     def reprJSON(self): # https://stackoverflow.com/questions/5160077/encoding-nested-python-object-in-json
#         d = dict()
#         for a, v in self.__dict__.items():
#             if (hasattr(v, "reprJSON")):
#                 d[a] = v.reprJSON()
#             elif a=="alleles":
#                 d["alleles"]={}
#                 for nt, alle in v.items():
#                     d["alleles"].update({nt: alle.reprJSON()})
#             else:
#                 d[a] = v
#         return d
# 
# class segment(object):
#     """ A sequence like object made up of locus objects
#             Attriutes:
#                 chr - the name of the chr
#                 seq - a list of loci
#             methods:
#                 append: append another position
#                 update: update base count at a position (loci base 1)
#                 consensus: calcuate the consensus sequence"""
#     def __init__(self,chr):
#         self.chr = chr
#         self.seq = []
#     def append_loci(self,loci):
#         if type(loci) is not locus:
#             raise ValueError('Only class locus can be appended to a segment object')
#         # if loci.chr!=self.chr:
#         #     raise ValueError('The loci chr does not match the segement chr')
#         if len(self.seq)>0 and loci.pos!=max([x.pos for x in self.seq])+1:
#             raise ValueError('The position of the loci does not match current segment length')
#         self.seq.append(loci)
#     def consensus(self,cutoff=None):
#         seg_consensus = ""
#         for loci in self.seq:
#             seg_consensus=seg_consensus+loci.calc_consensus(cutoff)
#         return seg_consensus
#     def locus(self,pos):
#         loci = [x for x in self.seq if x.pos==pos]
#         return loci[0]
#     def calc_coverage(self):
#         cov = []
#         for loci in self.seq:
#             cov.append(loci.coverage)
#         return cov
#     
#     def reprJSON(self): # https://stackoverflow.com/questions/5160077/encoding-nested-python-object-in-json
#         d = dict()
#         for a, v in self.__dict__.items():
#             if hasattr(v, "reprJSON"):
#                 d[a] = v.reprJSON()
#             elif a=="seq":
#                 d["seq"]=[]
#                 for l in v:
#                     d["seq"].append(l.reprJSON())
#             else:
#                 d[a] = v
#         return d


import unittest
import pysam
import copy
from scripts.seq_classes import locus, segment, allele


class test_loci(unittest.TestCase):
    def setUp(self):
        
        self.solution ={'A':allele("A"),
                        'T':allele("T"),
                        'C':allele("C"),

# Path: scripts/seq_classes.py
# def locus(self,pos):
#     loci = [x for x in self.seq if x.pos==pos]
#     return loci[0]
# 
# class locus(object):
#     """ A base which has the following characteristics 
#         Atrributes :
#             Chr : chromosome
#             pos : position on chromosome base 0
#             counts : a dictionary of { A : the number of As
#             T : the number of Ts
#             C : the number of Cs
#             G : the number of Gs
#             - : the number of of deletions    
#             }
#             add consensus.
#             add concat_pos
#         methods : 
#             update : update counts
#             calc_freqs :  calculate the frequency of each base
#             consensus : caculate the consensus sequence as this position 
#     """
#     def __init__(self,pos):
#         """
#         return a base object with chr and pos and starting counts of 0
#         Posisition is base 0 because this is python and I want to keep everything 
#         easy to remember. If it came from python it is base 0.
#         """
#         self.pos = pos
#         # self.alleles = {'A':allele("A"),
#         #                 'T':allele("T"),
#         #                 'C':allele("C"),
#         #                 'G':allele("G"),
#         #                 '-':allele("-")}
#         self.alleles = {}
#         self.coverage = 0
#         self.concat_pos = None
#         self.consensus = ''
# 
#     def update(self,base):
#         self.coverage = self.coverage+1
# 
#         if base in self.alleles.keys():
#             self.alleles[base].count+=1
#             
#         else:
#             self.alleles.update({base:allele(base)})
#             self.alleles[base].count+=1
# 
#         self.calc_freqs()
#         self.consensus = self.calc_consensus()
#     def calc_freqs(self):
#         for base in self.alleles.keys():
#             self.alleles[base].freq = self.alleles[base].count/self.coverage
#             
#     def calc_consensus(self,cutoff=None):
#         if self.coverage==0:
#             return '-'
#         else:
#             self.calc_freqs()
#             v=[y.freq for y  in self.alleles.values()] #values
#             k=list(self.alleles.keys()) # key
#             # check for cutoff method
#             if cutoff ==None:
#                 # Return the most common base
#                 return k[v.index(max(v))]
#             
#                     
#             else:
#                 # return the base that is above the cutoff
#                 if type(cutoff)!=float or (cutoff>1 or cutoff<0.5):
#                     raise ValueError('cutoff must be a float in [0.5,1.0] or nothing')
#                 indexes = [index for index, value in enumerate(v) if value > cutoff]
#                 if len(indexes)==1:
#                     consensus = k[indexes[0]]
#                 else:
#                     consensus = "N"
#                 return consensus
# 
#     def reprJSON(self): # https://stackoverflow.com/questions/5160077/encoding-nested-python-object-in-json
#         d = dict()
#         for a, v in self.__dict__.items():
#             if (hasattr(v, "reprJSON")):
#                 d[a] = v.reprJSON()
#             elif a=="alleles":
#                 d["alleles"]={}
#                 for nt, alle in v.items():
#                     d["alleles"].update({nt: alle.reprJSON()})
#             else:
#                 d[a] = v
#         return d
# 
# class segment(object):
#     """ A sequence like object made up of locus objects
#             Attriutes:
#                 chr - the name of the chr
#                 seq - a list of loci
#             methods:
#                 append: append another position
#                 update: update base count at a position (loci base 1)
#                 consensus: calcuate the consensus sequence"""
#     def __init__(self,chr):
#         self.chr = chr
#         self.seq = []
#     def append_loci(self,loci):
#         if type(loci) is not locus:
#             raise ValueError('Only class locus can be appended to a segment object')
#         # if loci.chr!=self.chr:
#         #     raise ValueError('The loci chr does not match the segement chr')
#         if len(self.seq)>0 and loci.pos!=max([x.pos for x in self.seq])+1:
#             raise ValueError('The position of the loci does not match current segment length')
#         self.seq.append(loci)
#     def consensus(self,cutoff=None):
#         seg_consensus = ""
#         for loci in self.seq:
#             seg_consensus=seg_consensus+loci.calc_consensus(cutoff)
#         return seg_consensus
#     def locus(self,pos):
#         loci = [x for x in self.seq if x.pos==pos]
#         return loci[0]
#     def calc_coverage(self):
#         cov = []
#         for loci in self.seq:
#             cov.append(loci.coverage)
#         return cov
#     
#     def reprJSON(self): # https://stackoverflow.com/questions/5160077/encoding-nested-python-object-in-json
#         d = dict()
#         for a, v in self.__dict__.items():
#             if hasattr(v, "reprJSON"):
#                 d[a] = v.reprJSON()
#             elif a=="seq":
#                 d["seq"]=[]
#                 for l in v:
#                     d["seq"].append(l.reprJSON())
#             else:
#                 d[a] = v
#         return d


# Path: test/consensus_test.py
import unittest
import pysam
import copy
from scripts.seq_classes import locus, segment, allele



class test_loci(unittest.TestCase):
    def setUp(self):
        
        self.solution ={'A':allele("A"),
                        'T':allele("T"),
                        'C':allele("C"),

                        'G':allele("G"),