
def get_reward_strongArm(corner_info: str, perf: dict):

    array = corner_info.split('_')
    corner = {
        'process': array[0],
        'temp': array[1],
        'vdd': array[2],
    }
    strongArm_range = {
        'Power': 4.5e-6,
        'delay': 10e-9,
        'reset': 7e-9,
        'reset_val': 0,
        'rise_val': float(corner['vdd']),
        'input_ref_noise': 5e-5,
    }

    dReset = perf['reset_val'] - strongArm_range['reset_val']
    dRise = strongArm_range['rise_val'] - perf['rise_val']

    std_reset = -(dReset - 0.05) / (dReset + 0.05)
    std_reset = min(0, std_reset)

    std_rise = -(dRise - 0.05) / (dRise + 0.05)
    std_rise = min(0, std_reset)

    std_noise = -(perf['input_ref_noise'] - strongArm_range['input_ref_noise']) / (perf['input_ref_noise'] +
                                                                                   strongArm_range['input_ref_noise'])
    std_noise = min(0, std_noise)

    std_delay = -(perf['delay'] - strongArm_range['delay']) / (perf['delay'] + strongArm_range['delay'])
    std_delay = min(0, std_delay)

    std_reset_delay = -(perf['reset'] - strongArm_range['reset']) / (perf['reset'] + strongArm_range['reset'])
    std_reset_delay = min(0, std_reset_delay)

    std_power = -(perf['Power'] - strongArm_range['Power']) / (perf['Power'] + strongArm_range['Power'])
    std_power *= 3
    std_power = max(-1, min(0, std_power))

    reward = std_power + std_delay + std_reset + std_noise + std_reset_delay + std_rise
    if reward >= -0.02:
        reward = 0.2

    return reward


def get_reward_fold(corner_info: str, perf: dict):

    array = corner_info.split('_')
    corner = {
        'process': array[0],
        'temp': array[1],
        'vdd': array[2],
    }

    range = {
        'gain': 60,
        'pm_dm': 60,
        'cmrr': 80,
        'psrr': 80,
        'rms_noise_out_dm':3e-4,
        'lg_ugb': 30e6,
    }

    stds = {}
    for key in {'gain', 'cmrr', 'psrr', 'pm_dm', 'lg_ugb'}:
        stds[key] = (perf[key] - range[key]) / (perf[key] + range[key])
        stds[key] = min(0, stds[key])

    for key in {'rms_noise_out_dm'}:
        perf[key] = max(0, perf[key])
        stds[key] = -(perf[key] - range[key]) / (perf[key] + range[key])
        stds[key] = min(0, stds[key])

    reward = 0
    for key, value in stds.items():
        reward += value

    if reward >= -0.02:
        reward = 0.2

    return reward


def get_reward_ng(corner_info: str, perf: dict):

    array = corner_info.split('_')
    corner = {
        'process': array[0],
        'temp': array[1],
        'vdd': array[2],
    }

    range = {
        'gain': 300,
        'ibias': 5e-3,
        'phm': 60,
        'ugbw': 15000000.001,
    }

    stds = {}
    for key in {'gain', 'phm', 'ugbw'}:
        stds[key] = (perf[key] - range[key]) / (perf[key] + range[key])
        stds[key] = min(0, stds[key])

    for key in {'ibias'}:
        perf[key] = max(0, perf[key])
        stds[key] = -(perf[key] - range[key]) / (perf[key] + range[key])
        stds[key] = min(0, stds[key])

    reward = 0
    for key, value in stds.items():
        reward += value

    if reward >= -0.02:
        reward = 0.2

    return reward