# Path: seqcluster/libs/utils.py
# def chdir(p):
# def safe_dirs(dirs):
# def safe_remove(fn):
# def safe_run(fn):
# def file_exists(fname):
# 
# Path: seqcluster/libs/parameters.py

# 
# Path: seqcluster/libs/mystats.py
# def up_threshold(x, s, p):
#     """function to decide if similarity is
#     below cutoff"""
#     if 1.0 * x/s >= p:
#         return True
#     elif stat.binom_test(x, s, p) > 0.01:
#         return True
#     return False
# 
# Path: seqcluster/libs/bayes.py
# def decide_by_bayes(list_c, s2p):
#     # for each cluster get seq ~ loci edges
#     loci_obj, seq_obj = s2p
#     seqs_in_c = _dict_seq_locus(list_c, loci_obj, seq_obj)
#     for s in seqs_in_c:
#         total = sum(seqs_in_c[s].values())
#         norm_values = 1.0 * np.array(seqs_in_c[s].values()) / total
#         prob = _bayes(dict(zip(seqs_in_c[s].keys(), norm_values)))
#         for clus in prob:
#             list_c[clus].idmembers[s] = prob.loci[clus]["position"]
#             # print "%s %s %s" % (s, clus, list_c[clus].idmembers[s])
#     return list_c


from collections import defaultdict
from progressbar import ProgressBar
from seqcluster.libs import utils
from seqcluster.libs import parameters
from seqcluster.libs.classes import *
from seqcluster.libs.mystats import up_threshold
from seqcluster.libs.bayes import decide_by_bayes
import operator
import os
import os.path as op
import copy
import math
import seqcluster.libs.logger as mylog
    :param c: cluster object

    :return ma: similarity matrix
    """
    ma = {}
    for idc in c:
        set1 = _get_seqs(c[idc])
        [ma.update({(idc, idc2): _common(set1, _get_seqs(c[idc2]), idc, idc2)}) for idc2 in c if idc != idc2 and (idc2, idc) not in ma]
    # logger.debug("_calculate_similarity_ %s" % ma)
    return ma


def _get_seqs(list_idl):
    """get all sequences in a cluster knowing loci"""
    seqs = set()
    for idl in list_idl.loci2seq:
        # logger.debug("_get_seqs_: loci %s" % idl)
        [seqs.add(s) for s in list_idl.loci2seq[idl]]
    # logger.debug("_get_seqs_: %s" % len(seqs))
    return seqs


def _common(s1, s2, i1, i2):
    """calculate the common % percentage of sequences"""
    c = len(set(s1).intersection(s2))
    t = min(len(s1), len(s2))
    pct = 1.0 * c / t * t
    is_gt = up_threshold(pct, t * 1.0, parameters.similar)
    logger.debug("_common: pct %s of clusters:%s %s = %s" % (1.0 * c / t, i1, i2, is_gt))
    if pct < parameters.similar and is_gt and pct > 0:

# Path: seqcluster/libs/utils.py
# def chdir(p):
# def safe_dirs(dirs):
# def safe_remove(fn):
# def safe_run(fn):
# def file_exists(fname):
# 
# Path: seqcluster/libs/parameters.py

# 
# Path: seqcluster/libs/mystats.py
# def up_threshold(x, s, p):
#     """function to decide if similarity is
#     below cutoff"""
#     if 1.0 * x/s >= p:
#         return True
#     elif stat.binom_test(x, s, p) > 0.01:
#         return True
#     return False
# 
# Path: seqcluster/libs/bayes.py
# def decide_by_bayes(list_c, s2p):
#     # for each cluster get seq ~ loci edges
#     loci_obj, seq_obj = s2p
#     seqs_in_c = _dict_seq_locus(list_c, loci_obj, seq_obj)
#     for s in seqs_in_c:
#         total = sum(seqs_in_c[s].values())
#         norm_values = 1.0 * np.array(seqs_in_c[s].values()) / total
#         prob = _bayes(dict(zip(seqs_in_c[s].keys(), norm_values)))
#         for clus in prob:
#             list_c[clus].idmembers[s] = prob.loci[clus]["position"]
#             # print "%s %s %s" % (s, clus, list_c[clus].idmembers[s])
#     return list_c


# Path: seqcluster/detect/metacluster.py
from collections import defaultdict
from progressbar import ProgressBar
from seqcluster.libs import utils
from seqcluster.libs import parameters
from seqcluster.libs.classes import *
from seqcluster.libs.mystats import up_threshold
from seqcluster.libs.bayes import decide_by_bayes
import operator
import os
import os.path as op
import copy
import math
import seqcluster.libs.logger as mylog

    :param c: cluster object

    :return ma: similarity matrix
    """
    ma = {}
    for idc in c:
        set1 = _get_seqs(c[idc])
        [ma.update({(idc, idc2): _common(set1, _get_seqs(c[idc2]), idc, idc2)}) for idc2 in c if idc != idc2 and (idc2, idc) not in ma]
    # logger.debug("_calculate_similarity_ %s" % ma)
    return ma


def _get_seqs(list_idl):
    """get all sequences in a cluster knowing loci"""
    seqs = set()
    for idl in list_idl.loci2seq:
        # logger.debug("_get_seqs_: loci %s" % idl)
        [seqs.add(s) for s in list_idl.loci2seq[idl]]
    # logger.debug("_get_seqs_: %s" % len(seqs))
    return seqs


def _common(s1, s2, i1, i2):
    """calculate the common % percentage of sequences"""
    c = len(set(s1).intersection(s2))
    t = min(len(s1), len(s2))
    pct = 1.0 * c / t * t
    is_gt = up_threshold(pct, t * 1.0, parameters.similar)
    logger.debug("_common: pct %s of clusters:%s %s = %s" % (1.0 * c / t, i1, i2, is_gt))
    if pct < parameters.similar and is_gt and pct > 0:

        pct = parameters.similar