# -*- coding: UTF-8 -*-
# !/usr/bin/python

import numpy as np
import joblib
import math

x_mean = np.array([
    83.8996, 97.0520, 36.8055, 126.2240, 86.2907,
    66.2070, 18.7280, 33.7373, -3.1923, 22.5352,
    0.4597, 7.3889, 39.5049, 96.8883, 103.4265,
    22.4952, 87.5214, 7.7210, 106.1982, 1.5961,
    0.6943, 131.5327, 2.0262, 2.0509, 3.5130,
    4.0541, 1.3423, 5.2734, 32.1134, 10.5383,
    38.9974, 10.5585, 286.5404, 198.6777,
    60.8711, 0.5435, 0.0615, 0.0727, -59.6769, 28.4551])

x_std = np.array([
    17.6494, 3.0163, 0.6895, 24.2988, 16.6459,
    14.0771, 4.7035, 11.0158, 3.7845, 3.1567,
    6.2684, 0.0710, 9.1087, 3.3971, 430.3638,
    19.0690, 81.7152, 2.3992, 4.9761, 2.0648,
    1.9926, 45.4816, 1.6008, 0.3793, 1.3092,
    0.5844, 2.5511, 20.4142, 6.4362, 2.2302,
    29.8928, 7.0606, 137.3886, 96.8997,
    16.1887, 0.4981, 0.7968, 0.8029, 160.8846, 29.5367])

mFMax = []
fSum_pre = []
fmax = []
fmin = []
grad_temp = []
hess_temp = []
All_grad1 = []
All_grad12 = []
All_grad24 = []
All_hess1 = []
f_index=[]
def kind_feature_filter(pos, dele=True):
    origin_f = 0
    res_f = 40
    grad1_f = 74  #
    grad12_f = 108
    grad24_f = 142
    hess1_f = 176  #
    hess12_f = 210
    hess24_f = 244
    mutation_f = 278
    mutation_max_f = 312

    # mutation12_f = 346
    mutation12h_f = 346
    sum_f = 380
    sum8_f = 414
    max_f = 448
    min_f = 482
    mean_f = 516
    var_f = 550
    cov1_f = 584
    cov2_f = 618
    cov_la_f = 652

    r_stat_f = 686  #
    g_stat_f = 690  #
    h_stat_f = 694
    m_stat_f = 698
    # gnb_f = 702
    f_energy = 702
    g_abs_sc = 736
    h_abs_sc = 770
    r_above_zero = 804
    r_below_zero = 838
    freq_max = 872

    # auto_var_1h = 904
    # auto_var_12h = 940
    # auto_var_24h = 974
    # auto_var_coef_1h = 1008
    # auto_var_coef_12h = 1042
    # auto_var_coef_24h = 1076

    skewness = 1110
    kurtosis = 1144
    extreme_measure = 1178

    f_length = 1008
    f_index = []

    f_temp = []
    for i in range(len(pos)):
        id = pos[i]
        if id == 1:
            for k in range(40):
                f_temp.append(k)
        elif id < 21:
            for k in range(34):
                f_temp.append((id - 1) * 34 + 6 + k)
        elif id < 25:
            for k in range(4):
                f_temp.append(686 + 4 * (id - 21) + k)
        elif id < 34:
            for k in range(34):
                f_temp.append(702 + (id - 25) * 34 + k)
    if dele:
        for j in range(f_length):
            if not np.isin(j, np.array(f_temp)):
                f_index.append(j)
    else:
        f_index = f_temp
    f_index = np.sort(f_index)
    return np.array(f_index)

def get_sepsis_score(feature, model):

    feature = genFeature(feature)
    # print(feature.dtype)
    # generate predictions
    label = model.predict(feature)
    prob = model.predict_proba(feature)
    # print(label, prob)
    # pb = 0.1
    # # print(prob)
    # if (prob[0][1] > pb):
    #     label = 1
    # else:
    #     label = 0
    return prob[0][1], label


def load_sepsis_model():
    clf = joblib.load('EasyEnsembleLightGBM.pkl')
    return clf


def imputer_missing_mean_numpy(testFtr, start=0):
    imr = np.load('imputer_mean_numpy.npy')
    h, w = testFtr.shape
    for i in range(h):
        for j in range(w):
            if np.isnan(testFtr[i, j]):
                testFtr[i, j] = imr[j + start]
    return testFtr


def imputer_missing_median_numpy(testFtr, start=0):
    imr = np.load('imputer_median_numpy.npy')
    h, w = testFtr.shape
    for i in range(h):
        for j in range(w):
            if np.isnan(testFtr[i, j]):
                testFtr[i, j] = imr[j + start]
    return testFtr

f_index=kind_feature_filter([5,7])
# 输入所有数据特征
def genFeature(data):
    global All_grad1, All_grad12, All_grad24, All_hess1,f_index
    exlen = 34
    # feature = data[:, :-1]
    feature = data
    h, w = feature.shape
    if h == 1:
        All_grad1 = []
        All_grad12 = []
        All_grad24 = []
        All_hess1 = []

    for j in range(w):
        for i in range(h):
            if np.isnan(feature[i, j]):
                feature[i, j] = searchNearValue(i, feature[:, j])

    for j in range(w):
        for i in range(h):
            if np.isnan(feature[i, j]):
                feature[i, j] = x_mean[j]

    # norm = data_norm(feature)
    res = residual_value(feature[:, :exlen])

    rMax = np.nanmax(res[-1])
    rMin = np.nanmin(res[-1])
    rMean = np.nanmean(res[-1])
    rSum = np.nansum(res[-1])
    rStat = np.hstack((rMax, rMin, rMean, rSum))
    rStat = np.reshape(rStat, (1, len(rStat)))

    grad1 = Grad1(res)
    grad12 = Grad12(res)
    grad24 = Grad24(res)
    grad = np.hstack((grad1, grad12, grad24))
    # grad = np.hstack((grad1, grad12))
    grad = np.reshape(grad, (1, len(grad)))

    gMax = np.nanmax(grad, axis=1)
    gMin = np.nanmin(grad, axis=1)
    gMean = np.nanmean(grad, axis=1)
    gSum = np.nansum(grad, axis=1)
    gStat = np.hstack((gMax, gMin, gMean, gSum))
    gStat = np.reshape(gStat, (1, len(gStat)))

    All_grad1.append(grad[0, :exlen])
    All_grad12.append(grad[0, exlen:2 * exlen])
    All_grad24.append(grad[0, 2 * exlen:3 * exlen])
    hess1 = Grad1(np.array(All_grad1))
    hess12 = Grad12(np.array(All_grad12))
    hess24 = Grad24(np.array(All_grad24))
    hess = np.hstack((hess1, hess12, hess24))
    # hess = np.hstack((hess1, hess24))
    hess = np.reshape(hess, (1, len(hess)))
    All_hess1.append(hess1)

    hMax = np.nanmax(hess, axis=1)
    hMin = np.nanmin(hess, axis=1)
    hMean = np.nanmean(hess, axis=1)
    hSum = np.nansum(hess, axis=1)
    hStat = np.hstack((hMax, hMin, hMean, hSum))
    hStat = np.reshape(hStat, (1, len(hStat)))

    mutation = mFactor(res)
    mutationMax = mFactorMax(res)
    # mutation12 = mFactor12(res)
    mutation12h = mFactor12h(res)
    mu = np.hstack((mutation, mutationMax, mutation12h))

    mMax = np.nanmax(mu, axis=1)
    mMin = np.nanmin(mu, axis=1)
    mMean = np.nanmean(mu, axis=1)
    mSum = np.nansum(mu, axis=1)
    mStat = np.hstack((mMax, mMin, mMean, mSum))
    mStat = np.reshape(mStat, (1, len(mStat)))
    # print(mStat.shape)

    fSum = f_sum(res)
    fSum8 = f_sum8h(res)
    fMax = f_max(res)
    fMin = f_min(res)
    fMean = f_mean(res)
    fVar = f_var(res)
    stat = np.hstack((fSum, fSum8, fMax, fMin, fMean, fVar))

    # fCov = cov_1d(feature[:, :exlen], [1, 2, 1])
    fCov = covFilter(feature[:, :exlen])
    norm = normalization(feature[:, :exlen])
    kernel = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
    fCov2 = cov_2d(norm, kernel / 16.0)
    laplace_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
    fCov_laplace = cov_2d(norm, laplace_kernel)
    cov = np.hstack((fCov, fCov2, fCov_laplace))

    fEnergy = abs_energy(res)
    gAbsSC, hAbsSC = absolute_sum(np.array(All_grad1), np.array(All_hess1))
    rAboveZero = count_above_zero(res)
    rBelowZero = count_below_zero(res)
    freqMax = fre_max(res)
    newf = np.hstack((fEnergy, gAbsSC, hAbsSC, rAboveZero, rBelowZero, freqMax))
    # feature = cov
    skewness = skewness_res(res)
    kurtosis = kurtosis_res(res)
    extreme_measure = fMax - fMin
    stat_append = np.hstack((skewness, kurtosis, extreme_measure))
    # print(grad.shape)
    # print(hess.shape)
    # print(mu.shape)
    # print(stat.shape)
    # print(cov.shape)
    # print(rStat.shape)
    # f = cov
    f = np.hstack((feature[h - 1:h, :], res[h - 1:h, :], grad, hess, mu, stat, cov, rStat, gStat, hStat, mStat, newf,
                   stat_append))
    f = ImputerMissingValue(f, 40, 'median')
    f=f[:,f_index]
    f = np.array(f).astype('float32')
    print(f.shape)
    return f


def ImputerMissingValue(feature, start=0, way='median'):
    if way == 'median':
        imr = np.load("feature_median_numpy.npy")
    elif way == 'mean':
        imr = np.load("feature_mean_numpy.npy")

    h, w = feature.shape
    for i in range(h):
        for j in range(w - start):
            if np.isnan(feature[i, j + start]) or np.isinf(feature[i, j + start]):
                feature[i, j + start] = imr[j + start]
    return feature


def searchNearValue(index, list):
    indexL = index
    while indexL >= 0:
        if np.isnan(list[indexL]) == False:
            return list[indexL]
        indexL = indexL - 1
    return list[index]


fMax = np.array([
    280.00, 100.00, 50.00, 300.00, 300.00, 300.00, 100.00, 100.00,
    100.00, 55.00, 4000.00, 7.93, 100.00, 100.00, 9961.00, 268.00,
    3833.00, 27.90, 145.00, 46.60, 37.50, 988.00, 31.00, 9.80,
    18.80, 27.50, 49.60, 440.00, 71.70, 32.00, 250.00, 440.00,
    1760.00, 2322.00, 100.00, 1.00, 1.00, 1.00, 23.99, 336.00
])

fMin = np.array([
    20.00, 20.00, 20.90, 20.00, 20.00, 20.00, 1.00, 10.00,
    -32.00, 0.00, -50.00, 6.62, 10.00, 23.00, 3.00, 1.00,
    7.00, 1.00, 26.00, 0.10, 0.01, 10.00, 0.20, 0.20,
    0.20, 1.00, 0.10, 0.01, 5.50, 2.20, 12.50, 0.10,
    34.00, 1.00, 14.00, 0.00, 0.00, 0.00, -5366.86, 1.00
])

x_mean = np.array([
    83.8996, 97.0520, 36.8055, 126.2240, 86.2907,
    66.2070, 18.7280, 33.7373, -3.1923, 22.5352,
    0.4597, 7.3889, 39.5049, 96.8883, 103.4265,
    22.4952, 87.5214, 7.7210, 106.1982, 1.5961,
    0.6943, 131.5327, 2.0262, 2.0509, 3.5130,
    4.0541, 1.3423, 5.2734, 32.1134, 10.5383,
    38.9974, 10.5585, 286.5404, 198.6777,
    60.8711, 0.5435, 0.0615, 0.0727, -59.6769, 28.4551])

x_std = np.array([
    17.6494, 3.0163, 0.6895, 24.2988, 16.6459,
    14.0771, 4.7035, 11.0158, 3.7845, 3.1567,
    6.2684, 0.0710, 9.1087, 3.3971, 430.3638,
    19.0690, 81.7152, 2.3992, 4.9761, 2.0648,
    1.9926, 45.4816, 1.6008, 0.3793, 1.3092,
    0.5844, 2.5511, 20.4142, 6.4362, 2.2302,
    29.8928, 7.0606, 137.3886, 96.8997,
    16.1887, 0.4981, 0.7968, 0.8029, 160.8846, 29.5367])

fN = fMax - fMin


def normalization(item):
    h, w = item.shape
    global fMin, fMax, fN
    temp = (item - fMin[:w]) / fN[:w]
    norm = np.ones_like(temp)
    lower = np.zeros_like(temp)
    temp = np.minimum(temp, norm)
    result = np.maximum(temp, lower)
    return result


def data_norm(data):
    norm = (data[-1] - x_mean) / x_std
    return np.reshape(norm, (1, len(norm)))


def Grad1(data):
    h, w = data.shape
    grad = np.zeros(w)
    grad[:] = np.nan
    if h > 1:
        grad = data[-1, :] - data[-2, :]
    return grad


def covFilter(feature):
    h, w = feature.shape
    f = np.full((h + 2, w), 0)
    f[2:, :] = feature
    result = np.full((1, w), np.nan)

    result[0, :] = (f[-3, :] + f[-2, :] * 2 + f[-1, :]) / 4
    return np.reshape(result, (1, w))


def Grad12(data):
    h, w = data.shape
    grad = np.zeros(w)
    grad[:] = np.nan
    if h >= 13:
        grad = data[-1, :] - data[-13, :]
    elif h >= 7:
        grad = data[-1, :] - data[0, :]

    return grad


def Grad24(data):
    h, w = data.shape
    grad = np.zeros(w)
    grad[:] = np.nan
    if h >= 25:
        grad = data[-1, :] - data[-25, :]
    elif h >= 16:
        grad = data[-1, :] - data[0, :]
    return grad


def mFCac(data):
    h, w = data.shape
    m_t = np.nanmean(data, axis=0)
    s_t = np.nanstd(data, axis=0)
    for i in range(w):
        if np.isnan(m_t[i]):
            # m_t[i] = x_mean[i]
            m_t[i] = 0.001
        if np.isnan(s_t[i]):
            s_t[i] = x_std[i]
        if m_t[i] < 0.001 and m_t[i] >= 0:
            m_t[i] = 0.001
        elif m_t[i] > -0.001 and m_t[i] < 0:
            m_t[i] = -0.001
    return np.divide(s_t, m_t)


def mFactor(data):
    h, w = data.shape
    mF = np.zeros((1, w))
    mF[0, :] = np.nan
    if h > 1:
        mF[0, :] = mFCac(data)
    return mF


def mFactorMax(data):
    global mFMax
    h, w = data.shape
    mF = np.zeros((1, w))
    mF[:] = np.nan
    if h == 1:
        mFMax = []
    if h > 11:
        mF = mFCac(data[h - 12:h, :])
        if len(mFMax) >= 2:
            # splitV = np.nanmean(np.array(mFMax), axis=0)
            splitV = np.nanmedian(np.array(mFMax), axis=0)
            for j in range(len(splitV)):
                if splitV[j] > mF[j]:
                    min = np.nanmin(np.array(mFMax)[:, j], axis=0)
                    mF[j] = [min, mF[j]][bool(min > mF[j])]
                else:
                    max = np.nanmax(np.array(mFMax)[:, j], axis=0)
                    mF[j] = [max, mF[j]][bool(max < mF[j])]
        mFMax.append(mF)
        # print(mFMax)
        mF = np.reshape(mF, (1, w))
    return mF


index_i = 0
m_max = 0


def mFactor12(data):
    h, w = data.shape
    global index_i, m_max
    if h == 1:
        index_i = 0
        m_max = 0
    mF = np.zeros((1, w))
    mF[0, :] = np.nan

    if h < 12:
        return mF
    elif h < 37:
        for j in range(h - 11):
            m_t_mean = np.nanmean(data[j:j + 11, :], axis=0)
            m_t_max = np.nanmax(data[j:j + 11, :], axis=0)
            m_t_min = np.nanmin(data[j:j + 11, :], axis=0)
            m_t = m_t_mean / ((m_t_max - m_t_min) + 1e-3)
            m_t_all = np.nansum(m_t[:8])
            if m_t_all > m_max:
                m_max = m_t_all
                index_i = j
        if h - index_i <= 12:
            mF[0, :] = mFCac(data[index_i:h, :])
        else:
            k = int((h - index_i - 1) / 12)
            # print('h', h, index_i + k * 12, index_i)
            mF[0, :] = mFCac(data[index_i + k * 12:h, :])
    else:
        k = int((h - index_i - 1) / 12)
        # print('h', h, index_i + k * 12, index_i)
        mF[0, :] = mFCac(data[index_i + k * 12:h, :])
    return mF


def mFactor12h(data):
    h, w = data.shape
    mF = np.zeros((1, w))
    mF[0, :] = np.nan
    if h >= 12:
        mF[0, :] = mFCac(data[h - 12:h, :])
    return mF


def f_sum(data):
    global fSum_pre
    # print(fSum_pre, data.shape)
    h, w = data.shape
    if h == 1:
        fSum_pre = data
        # print(fSum_pre)
        return data
    else:
        thred = np.full((w), 1000000)
        s = np.vstack((fSum_pre, data[-1, :]))
        temp = np.nanmin(np.vstack((np.nansum(s, axis=0), thred)), axis=0)
        fSum_pre = temp
        return np.reshape(temp, (1, w))


def f_sum8h(data):
    h, w = data.shape
    s = np.zeros((1, w))
    s[0, :] = np.nan
    if h >= 8:
        s[0, :] = np.nansum(data[h - 8:h, :], axis=0)
    return s


def f_max(data):
    global fmax
    h, w = data.shape

    if h == 1:
        fmax = data
        return data

    m = np.zeros(w)
    m[:] = np.nan
    m = np.nanmax(np.vstack((fmax, data[-1, :])), axis=0)
    fmax = m
    return np.reshape(m, (1, w))


def f_min(data):
    global fmin
    h, w = data.shape

    if h == 1:
        fmin = data
        return data

    m = np.zeros(w)
    m[:] = np.nan
    m = np.nanmin(np.vstack((fmin, data[-1, :])), axis=0)
    fmin = m
    return np.reshape(m, (1, w))


def f_mean(data):
    h, w = data.shape
    m = np.zeros(w)
    m[:] = np.nan
    m = np.nanmean(data, axis=0)
    return np.reshape(m, (1, w))


def f_var(data):
    h, w = data.shape
    m = np.zeros(w)
    m[:] = np.nan
    m = np.nanvar(data, axis=0)
    return np.reshape(m, (1, w))


def f_median(data):
    h, w = data.shape
    m = np.zeros(w)
    m[:] = np.nan
    m = np.nanmedian(data, axis=0)
    return np.reshape(m, (1, w))


def residual_value(feature):
    h, w = feature.shape
    data = np.full((h, w), x_mean[0:w])
    return feature - data


def cov_1d(feature, kernel):
    n = len(kernel)
    h, w = feature.shape
    result = np.full((1, w), np.nan)
    k_sum = 0
    if h < n:
        for i in range(h):
            result += kernel[n - i - 1] * feature[-i - 1]
            k_sum += kernel[n - i - 1]
        result = result / k_sum
        return np.reshape(result, (1, w))
    f = feature[-n:, :]
    for i in range(n):
        result += kernel[i] * f[-n + i, :]
    result = result / np.sum(kernel)
    return np.reshape(result, (1, w))


def cov_2d(feature, kernel):
    h, w = feature.shape
    kh, kw = kernel.shape
    if kw % 2 == 0:
        print("kernel error")
    tmp = np.zeros((h + kh - 1, w + (kw - 1)), dtype='float32')
    tmp[kh - 1:, kw - 1:] = feature
    result = np.full((1, w), np.nan)
    for j in range(w):
        t = tmp[-kh:, j:j + kw] * kernel
        result[0, j] = np.sum(t)
    return result


def compare(value, left, right):
    if np.isnan(value):
        return 0
    if value > right:
        return 1
    elif value > left:
        return 0
    else:
        return -1


def gen_obs(list):
    result = []
    result.append(compare(list[0], 60, 150))
    result.append(compare(list[1], 91, 99))
    result.append(compare(list[2], 36.5, 37.3))
    result.append(compare(list[3], 90, 139))
    result.append(compare(list[4], 65, 110))
    result.append(compare(list[5], 50, 92))
    result.append(compare(list[6], 12, 60))
    result.append(compare(list[7], 35, 45))
    result.append(compare(list[8], -10, 6))
    result.append(compare(list[9], 23, 30))
    result.append(compare(list[10], 0.6, 0.98))
    result.append(compare(list[11], 6, 8))
    return result


def get_obsfeature(feature):
    h, w = feature.shape
    result = []
    for i in range(h):
        result.append(gen_obs(feature[i, :12]))
    return np.reshape(result, (h, 12))


def fre_max(feature):
    f = np.copy(feature)
    h, w = f.shape
    m = np.zeros((1, w))
    if h > 1:
        sp = np.fft.fft(f, axis=0)
        max_f = np.zeros(w)
        for k in range(h):
            max_f = np.max(np.vstack((np.sqrt(sp[k].real ** 2 + sp[k].imag ** 2), max_f)), axis=0)
        m = np.reshape(max_f, (1, w))
    return np.array(m)


energy_pre = []


def abs_energy(feature):
    global energy_pre
    f = np.copy(feature)
    h, w = f.shape
    if h == 1:
        energy_pre = np.zeros(w)
    energy_pre += np.power(feature[-1], 2)
    m = np.reshape(np.copy(energy_pre), (1, w))
    # print(m)
    return m


abs_grad = []
abs_hess = []


def absolute_sum(grad, hess):
    global abs_grad, abs_hess
    ##NaN处理
    h, w = np.array(grad).shape
    gd = np.copy(grad)
    hs = np.copy(hess)
    for j in range(w):
        if np.isnan(gd[-1, j]):
            gd[-1, j] = 0
        if np.isnan(hs[-1, j]):
            hs[-1, j] = 0
    if h == 1:
        abs_grad = np.zeros(w)
        abs_hess = np.zeros(w)
    abs_grad += np.abs(gd[-1])
    abs_hess += np.abs(hs[-1])
    g1 = np.reshape(np.copy(abs_grad), (1, w))
    h1 = np.reshape(np.copy(abs_hess), (1, w))
    return g1, h1


count_above = []


def count_above_zero(feature):
    global count_above
    h, w = np.array(feature).shape
    if h == 1:
        count_above = np.zeros(w)
    count_above += feature[-1] > 0
    m = np.reshape(np.copy(count_above), (1, w))
    return m


count_below = []


def count_below_zero(feature):
    global count_below
    h, w = np.array(feature).shape
    if h == 1:
        count_below = np.zeros(w)
    count_below += feature[-1] < 0
    m = np.reshape(np.copy(count_below), (1, w))
    return m


pre_power_3_skewness = []
pre_power_2_skewness = []


def skewness_res(res_f):
    global pre_power_3_skewness, pre_power_2_skewness
    res = np.copy(res_f)
    h, w = res.shape
    # sn = np.zeros(w)
    if h == 1:
        pre_power_3_skewness = np.zeros(w)
        pre_power_2_skewness = np.zeros(w)
    pre_power_3_skewness = np.vstack((pre_power_3_skewness, np.power(res[-1], 3)))
    pre_power_2_skewness = np.vstack((pre_power_2_skewness, np.power(res[-1], 2)))
    up = math.sqrt(h) * np.nansum(pre_power_3_skewness, axis=0)
    down = np.power(np.nansum(pre_power_2_skewness, axis=0), 1.5)
    for j in range(w):
        if down[j] < 0.00001:
            down[j] = 0.0001
    sn = up / down
    return np.reshape(sn, (1, w))


pre_power_4_kurtosis = []
pre_power_2_kurtosis = []


def kurtosis_res(res_f):
    global pre_power_4_kurtosis, pre_power_2_kurtosis
    res = np.copy(res_f)
    h, w = res.shape
    if h == 1:
        pre_power_4_kurtosis = np.zeros(w)
        pre_power_2_kurtosis = np.zeros(w)
    pre_power_4_kurtosis = np.vstack((pre_power_4_kurtosis, np.power(res[-1], 4)))
    pre_power_2_kurtosis = np.vstack((pre_power_2_kurtosis, np.power(res[-1], 2)))
    up = h * np.nansum(pre_power_4_kurtosis, axis=0)
    down = np.power(np.nansum(pre_power_2_kurtosis, axis=0), 2)
    for j in range(w):
        if down[j] < 0.00001:
            down[j] = 0.0001
    ks = up / down - 3
    return np.reshape(ks, (1, w))


def extremum_measure_sofvariation(res_f):
    res = np.copy(res_f)
    h, w = res.shape
    if h == 1:
        return np.zeros((1, w))

    max_res = np.nanmax(res, axis=0)
    min_res = np.nanmin(res, axis=0)
    es = max_res - min_res
    return np.reshape(es, (1, w))


if __name__ == "__main__":
    load_sepsis_model()
