import numpy as np
import sys
from scipy.special import erfcinv
from ... comm_tools import calculation as calcu

def ber2q(ber):
    '''
	Q=BER2Q(BER) Converts the bit-error rate in Q-factor [dB]
	using the formula:Q=20*log10( sqrt(2) * erfcinv(2*ber))
	As a reference (BER -> Q [dB}): 
						1e-3 -> 9.80		8e-4 ~= 10
						1e-5 -> 12.60		2e-4 ~= 11
						1e-9 -> 15.56	
    Parameters:
    ber: float
    bit error rate

    Returns:
    q: float
    Q factor calculated based on conversion formula
    '''
    if ber >= 0.49:
        ber = 0.499999
    elif ber == 0:
        ber = sys.float_info.min
    q = 20 * np.log10(np.sqrt(2) * erfcinv(2 * ber))
    return q

def constellation2q(tx_sig, rx_sig, mode = 'calcu'):
    """
    Calculate the Q factor (quality factor) of the transmission process according 
    to the sending data and receiving data
    Parameters:
    tx_sig: array_like
    Transmission data sequence
    rx_sig: array_like
    Received data sequence
    mode: str, optional
    Calculation mode

    Returns:
    q: float
    Q factor calculated by formula based on signal power and variance
    """
    if mode == 'normfit':
        var, _, sig_p, _, _= calcu.noise_var_esti(tx_sig, rx_sig, m)
    else:
        var, _, sig_p, _ = calcu.noise_var_esti(tx_sig, rx_sig)
    if var == 0:
       var = sys.float_info.min
    
    q = 10 * np.log10(sig_p / var)
    return q