## This file is used to generate different types of distributions
## It is used to generate data for training and testing of neural networks
## any new method added here will automatically be used in training


import traceback
import scipy.stats as scipys
import numpy as np
from numpy.random import default_rng
from sklearn.preprocessing import minmax_scale

# import inspect


target_ratio = 0.9
max_spikes_percentage = 0.1
verbose = True
illustrate = True


def _printt(toprint):
    if verbose == True:
        print(toprint)
        # print(inspect.stack()[0][3])
        # print(inspect.stack()[1][3])
        # print(inspect.stack()[2][3])
        # print(inspect.stack()[1][2])
        # print(inspect.stack()[1][1])

    else:
        pass


def _normalize_to_beta_values_ranges(inputt):
    # normalize distribution within 0 and 1
    outputt = minmax_scale(inputt)
    return outputt


def _check_05_ratio(inputt, methylation_status, size, **kwargs):
    """
    This function checks if ration of less and more than 0.5 is correct
    Attention!
    Different rule is applied to indifferent
    """
    inputt = inputt.copy()

    less = len(np.where((inputt < 0.5))[0])
    more = len(np.where((inputt > 0.5))[0])
    full_len = len(inputt)

    if methylation_status == True:
        ratio = more / full_len
        _printt(f"ratio from ratio check {more} / {full_len} = {ratio}")

    elif methylation_status == False:
        ratio = less / full_len
    else:
        less = len(np.where((inputt < 0.5))[0])
        more = len(np.where((inputt > 0.5))[0])
        exactly = len(np.where((inputt == 0.5))[0])

        dif = len(np.where((inputt > 0.4) & (inputt <= 0.6))[0])

        indif = 2 - target_ratio

        if (less < (indif * more)) and (
            more < (indif * less) and (exactly < (indif * size))
        ):
            _printt(f"center: {dif}/less: {less}/more: {more}  exact: {exactly}")
            ratio_status = False
            return ratio_status
        else:
            ratio_status = True
            return ratio_status

    if ratio > target_ratio:
        ratio_status = False

        return ratio_status
    else:
        ratio_status = True
        return ratio_status


def _check_range_01(inputt, **kwargs):
    if np.min(inputt) < 0:
        return True
    elif np.max(inputt) > 1:
        return True
    else:
        return False


def _rules(kwargs):
    rules_values = [_check_05_ratio(**kwargs), _check_range_01(**kwargs)]
    _printt(f"rules values {rules_values}")
    if True in rules_values:
        return True
    else:
        return False


def _add_spikes(inputt, spikes_percentage):
    inputt_len = len(inputt)
    n_spikes = int(inputt_len * spikes_percentage)
    spikes_rng = default_rng()
    n_spikes = spikes_rng.integers(0, n_spikes)
    for n in range(n_spikes):
        updown = spikes_rng.integers(0, 2)

        if updown == 0:

            # draws random number to subtract from single array value, random number is lower than basic number so it does not reach negative values
            try:
                x = np.ceil(np.multiply(inputt[n], 10))
                x = np.where(x > 1, x, 1)
                n_subtract = spikes_rng.integers(x) / 10
                inputt[n] = inputt[n] - n_subtract
            except Exception:
                print(traceback.format_exc())
        else:

            try:
                x = np.multiply(1 - inputt[n], 10)
                x = np.where(x > 1, x, 1)

                n_add = spikes_rng.integers(x) / 10
                inputt[n] = inputt[n] + n_add
            except Exception:
                print(traceback.format_exc())

    return inputt


def generate_poisson(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(3, 10) / 10
                mu = rng3.integers(1, 100) / 10

                beta = scipys.poisson.rvs(mu=mu, loc=loc, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 5) / 10
                mu = rng3.integers(1, 100) / 10

                beta = scipys.poisson.rvs(mu=mu, loc=loc, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:
            loc = 0
            rules_value = True
            methylation_status = None
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10
                mu = rng3.integers(1, 100) / 10

                beta = scipys.poisson.rvs(mu=mu, loc=loc, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_normal(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 10)
                step = rng2.integers(0, 10) / 10
                mu = rng3.integers(1, 100) / 10

                beta = scipys.norm.rvs(size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 10)
                step = rng2.integers(0, 10) / 10

                beta = scipys.norm.rvs(size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:

            rules_value = True
            methylation_status = None
            while rules_value:
                squeeze = rng1.integers(1, 10)
                step = rng2.integers(0, 10) / 10

                beta = scipys.norm.rvs(size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze
                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_dweibull(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10
                c = rng3.integers(20, 100) / 10

                beta = scipys.dweibull.rvs(c, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:

            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10
                c = rng3.integers(20, 100) / 10

                beta = scipys.dweibull.rvs(c, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:

            rules_value = True
            methylation_status = None
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10
                c = rng3.integers(20, 100) / 10

                beta = scipys.dweibull.rvs(c, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_nmodal(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    def bimodal():
        x = np.random.normal(loc=-10, scale=1, size=100)
        y = np.random.normal(loc=10, scale=0.5, size=100)

        xy = np.concatenate([y, x])
        x_eval = np.linspace(xy.min() - 1, xy.max() + 1, size)
        beta = scipys.gaussian_kde(xy, bw_method="silverman")(x_eval)
        return beta

    def trimodal():
        x = np.random.normal(loc=-10, scale=1, size=100)
        y = np.random.normal(loc=10, scale=0.5, size=100)
        z = np.random.normal(loc=2, scale=0.5, size=50)
        xy = np.concatenate([y, x, z])
        x_eval = np.linspace(xy.min() - 1, xy.max() + 1, size)
        beta = scipys.gaussian_kde(xy, bw_method="silverman")(x_eval)
        return beta

    not_within = True
    while not_within:
        if methylation_status == True:

            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(3, 10)
                step = rng2.integers(40, 100) / 100
                biortri = rng3.integers(2)

                if biortri == 0:
                    beta = bimodal()
                else:
                    beta = trimodal()
                beta = (beta / squeeze) + step

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:

            rules_value = True
            while rules_value:
                squeeze = rng1.integers(3, 10)
                step = rng2.integers(0, 40) / 100
                biortri = rng3.integers(2)

                if biortri == 0:
                    beta = bimodal()
                else:
                    beta = trimodal()
                beta = (beta / squeeze) + step

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:
            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 4)
                step = rng2.integers(0, 100) / 100
                biortri = rng3.integers(2)

                if biortri == 0:
                    beta = bimodal()
                else:
                    beta = trimodal()
                beta = (beta / squeeze) + step

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_hypergeom(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            loc = 0
            rules_value = True
            while rules_value:

                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10

                M = rng3.integers(2, 10)
                n = rng4.integers(1, 10)
                N = rng5.integers(1, 10)

                if N >= M:
                    N = M - 1
                if n <= n:
                    n = M - 1

                beta = scipys.hypergeom.rvs(M=M, n=n, N=N, size=size)

                beta = _normalize_to_beta_values_ranges(beta)
                beta = (beta / squeeze) + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)

                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(2, 5)

                step = rng2.integers(0, 7) / 10
                M = rng3.integers(2, 10)
                n = rng4.integers(1, 10)
                N = rng5.integers(1, 10)

                # check if N and n are correct
                if N >= M:
                    N = M - 1
                if n <= n:
                    n = M - 1

                beta = scipys.hypergeom.rvs(M=M, n=n, N=N, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(2, 5)

                step = rng2.integers(0, 10) / 10
                M = rng3.integers(2, 10)
                n = rng4.integers(1, 10)
                N = rng5.integers(1, 10)

                # check if N and n are correct
                if N >= M:
                    N = M - 1
                if n <= n:
                    n = M - 1

                beta = scipys.hypergeom.rvs(M=M, n=n, N=N, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_betabinom(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            rules_value = True
            while rules_value:

                squeeze = rng1.integers(10, 40) / 10
                step = rng2.integers(0, 100) / 100
                n = rng3.integers(5, 10)

                a = rng4.integers(1, 6)
                b = rng5.integers(9, 15)

                beta = scipys.betabinom.rvs(n, a, b, size=size)

                beta = _normalize_to_beta_values_ranges(beta)
                inverse = rng4.choice([0, 1])
                beta = np.abs(beta - inverse)
                beta = beta / squeeze
                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)

                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(10, 40) / 10
                step = rng2.integers(0, 100) / 100
                n = rng3.integers(5, 10)
                a = rng4.integers(1, 6)
                b = rng5.integers(9, 15)

                beta = scipys.betabinom.rvs(n, a, b, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                inverse = rng4.choice([0, 1])
                beta = np.abs(beta - inverse)
                beta = beta / squeeze
                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:
            rules_value = True
            while rules_value:

                squeeze = rng1.integers(10, 40) / 10
                step = rng2.integers(0, 100) / 100

                n = rng3.integers(5, 10)
                a = rng4.integers(1, 6)
                b = rng5.integers(9, 15)

                beta = scipys.betabinom.rvs(n, a, b, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                inverse = rng4.choice([0, 1])
                beta = np.abs(beta - inverse)
                beta = beta / squeeze
                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_dlaplace(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            loc = 0
            rules_value = True
            while rules_value:

                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 10) / 10
                a = rng3.integers(50, 200) / 100

                beta = scipys.dlaplace.rvs(a=a, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(1, 5)
                step = rng2.integers(0, 4) / 10
                a = rng3.integers(50, 200) / 100

                beta = scipys.dlaplace.rvs(a=a, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:
            loc = 0
            rules_value = True
            methylation_status = None
            while rules_value:
                squeeze = rng1.integers(1, 2)
                step = rng2.integers(0, 10) / 10
                a = rng3.integers(10, 30) / 100

                beta = scipys.dlaplace.rvs(a=a, size=size)
                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_uniform(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            rules_value = True
            while rules_value:
                start = rng1.integers(0, 10) / 10
                stop = rng2.integers(0, 10) / 10
                beta = np.linspace(start, stop, size)

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:

            rules_value = True
            while rules_value:
                start = rng1.integers(0, 10) / 10
                stop = rng2.integers(0, 10) / 10
                beta = np.linspace(start, stop, size)

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:

            rules_value = True
            methylation_status = None
            while rules_value:
                start = rng1.integers(0, 10) / 10
                stop = rng2.integers(0, 10) / 10
                dif = np.abs(start - stop)
                while dif < 0.1:
                    start = rng1.integers(0, 10) / 10
                    stop = rng2.integers(0, 10) / 10
                    dif = np.abs(start - stop)

                beta = np.linspace(start, stop, size)

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def generate_skewnorm(size, methylation_status):
    rng1 = default_rng()
    rng2 = default_rng()
    rng3 = default_rng()
    rng4 = default_rng()
    rng5 = default_rng()

    not_within = True
    while not_within:
        if methylation_status == True:

            rules_value = True
            while rules_value:
                squeeze = rng1.integers(10, 100) / 10
                step = rng2.integers(0, 10) / 10
                a = 1
                while a == 1:
                    a = rng3.integers(0, 80) - 40

                beta = scipys.skewnorm.rvs(a=a, size=size)

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze

                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        elif methylation_status == False:
            loc = 0
            rules_value = True
            while rules_value:
                squeeze = rng1.integers(10, 100) / 10
                step = rng2.integers(0, 10) / 10
                a = 1
                while a == 1:
                    a = rng3.integers(0, 80) - 40

                beta = scipys.skewnorm.rvs(a=a, size=size)

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze

                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)
                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)

        else:

            rules_value = True
            methylation_status = None
            while rules_value:
                squeeze = rng1.integers(10, 50) / 10
                step = rng2.integers(0, 10) / 10
                a = 1
                while a == 1:
                    a = rng3.integers(0, 80) - 40

                beta = scipys.skewnorm.rvs(a=a, size=size)

                beta = _normalize_to_beta_values_ranges(beta)
                beta = beta / squeeze

                beta = beta + step

                rules_params = {
                    "inputt": beta,
                    "methylation_status": methylation_status,
                    "size": size,
                }
                rules_value = _rules(rules_params)

                _printt(f"Does beta array break the rules? {rules_value}")

            beta = _add_spikes(beta, max_spikes_percentage)
        not_within = False
        rng4.shuffle(beta)
        if np.max(beta) > 1 or np.min(beta) < 0:
            not_within = True
        else:
            not_within = False
    return beta


def main():

    for n in range(0, 1):
        size = 1000
        parameters = [True, False, None]

        functions = [
            generate_poisson,
            generate_normal,
            generate_dweibull,
            generate_nmodal,
            generate_hypergeom,
            generate_betabinom,
            generate_dlaplace,
            generate_uniform,
            generate_skewnorm,
        ]

        for function in functions:
            for param in parameters:
                for n in range(5):
                    params = [size, param]
                    r = function(*params)

                    aname = function.__name__
                    aparam_name = ""
                    if param == True:
                        aparam_name = "hypermethylation"
                    elif param == False:
                        aparam_name = "hypomethylation"
                    elif param == None:
                        aparam_name = "indeterminate"
                    else:
                        pass
                    title = f"param {aparam_name}  , function {aname}"
                    print(title)
                    if illustrate == True:

                        vsz.distribution_visualization_save_train(r, title)

        _printt(f"maximum value {np.max(r)}")
        _printt(f"minimum value {np.min(r)}")


if __name__ == "__main__":
    import visualization as vsz

    print("Running directly")
    main()


else:

    print("Importing distribution_generator")
    verbose = False
