# Path: covest/constants.py
# MAX_EXP = 200
# GRID_DEPTH = 3
# INF = float('inf')
# VERBOSE = True
# PLOT_LOG_SCALE = True
# USE_BIGFLOAT = False
# STEP = 1.1
# OPTIMIZATION_METHOD = 'L-BFGS-B'
# INITIAL_GRID_COUNT = 20
# INITIAL_GRID_STEP = 3
# DEFAULT_ERR_SCALE = 1
# DEFAULT_K = 21
# DEFAULT_READ_LENGTH = 100
# DEFAULT_REPEAT_MODEL = 0
# DEFAULT_MIN_SINGLECOPY_RATIO = 0.3
# AUTO_SAMPLE_TARGET_COVERAGE = 12
# AUTO_TRIM_PRECISION = 6
# NOISE_THRESHOLD = 10**-6
# MAX_ERRORS = 8
# MAX_NOTRIM = 25
#     DEFAULT_THREAD_COUNT = cpu_count()
#     DEFAULT_THREAD_COUNT = 2
# 
# Path: covest/inverse.py
# def inverse(f, delta=1e-8):
#     """Given a function y = f(x) that is a monotonically increasing function on
#     non-negative numbers, return the function x = f_1(y) that is an approximate
#     inverse, picking the closest value to the inverse, within delta."""
#     def derivative(func):
#         return lambda y: (func(y + delta) - func(y)) / delta
# 
#     def root(y):
#         return lambda x: f(x) - y
# 
#     def newton(y, iters=15):
#         guess = float(y) / 2
#         rootfunc = root(y)
#         derifunc = derivative(rootfunc)
#         d = (rootfunc(guess) / derifunc(guess))
#         while abs(d) > delta:
#             guess -= d
#             d = (rootfunc(guess) / derifunc(guess))
# 
#         return guess
#     return newton


import subprocess
import sys
from math import log, exp
from covest import constants
from .inverse import inverse
        return
    sys.stderr.write(message + "\n")


def safe_int(x):
    return int(x) if x != float('inf') else None


def fix_zero(x, val=1):
    if x == 0:
        return val
    else:
        return x


def safe_log(x):
    if x is None or x <= 0:
        return -constants.INF
    return log(x)


def estimate_p(cc, alpha):
    return (cc * (alpha - 1)) / (alpha * cc - alpha - cc)


def kmer_to_read_coverage(coverage, k, r):
    return coverage * r / (r - k + 1)


def fix_coverage(coverage):

# Path: covest/constants.py
# MAX_EXP = 200
# GRID_DEPTH = 3
# INF = float('inf')
# VERBOSE = True
# PLOT_LOG_SCALE = True
# USE_BIGFLOAT = False
# STEP = 1.1
# OPTIMIZATION_METHOD = 'L-BFGS-B'
# INITIAL_GRID_COUNT = 20
# INITIAL_GRID_STEP = 3
# DEFAULT_ERR_SCALE = 1
# DEFAULT_K = 21
# DEFAULT_READ_LENGTH = 100
# DEFAULT_REPEAT_MODEL = 0
# DEFAULT_MIN_SINGLECOPY_RATIO = 0.3
# AUTO_SAMPLE_TARGET_COVERAGE = 12
# AUTO_TRIM_PRECISION = 6
# NOISE_THRESHOLD = 10**-6
# MAX_ERRORS = 8
# MAX_NOTRIM = 25
#     DEFAULT_THREAD_COUNT = cpu_count()
#     DEFAULT_THREAD_COUNT = 2
# 
# Path: covest/inverse.py
# def inverse(f, delta=1e-8):
#     """Given a function y = f(x) that is a monotonically increasing function on
#     non-negative numbers, return the function x = f_1(y) that is an approximate
#     inverse, picking the closest value to the inverse, within delta."""
#     def derivative(func):
#         return lambda y: (func(y + delta) - func(y)) / delta
# 
#     def root(y):
#         return lambda x: f(x) - y
# 
#     def newton(y, iters=15):
#         guess = float(y) / 2
#         rootfunc = root(y)
#         derifunc = derivative(rootfunc)
#         d = (rootfunc(guess) / derifunc(guess))
#         while abs(d) > delta:
#             guess -= d
#             d = (rootfunc(guess) / derifunc(guess))
# 
#         return guess
#     return newton


# Path: covest/utils.py
import subprocess
import sys
from math import log, exp
from covest import constants
from .inverse import inverse

        return
    sys.stderr.write(message + "\n")


def safe_int(x):
    return int(x) if x != float('inf') else None


def fix_zero(x, val=1):
    if x == 0:
        return val
    else:
        return x


def safe_log(x):
    if x is None or x <= 0:
        return -constants.INF
    return log(x)


def estimate_p(cc, alpha):
    return (cc * (alpha - 1)) / (alpha * cc - alpha - cc)


def kmer_to_read_coverage(coverage, k, r):
    return coverage * r / (r - k + 1)


def fix_coverage(coverage):

    return inverse(lambda c: (c - c * exp(-c)) / (1 - exp(-c) - c * exp(-c)))(coverage)