def calculate_auc_diff(auc_structure_1, auc_structure_2, sort_order):
    """
    returns the absolute value of the difference in ROC AUC values and corresponding statistics.
    specifically, |AUC1 - AUC2|, the 95% confidence interval, and the 2-sided p-value
    :param sort_order:
    :param auc_structure_1: list [(id, best_score, best_query, status, fpf, tpf), ..., ]
    :param auc_structure_2: list [(id, best_score, best_query, status, fpf, tpf), ..., ]
    :return (AUC1-AUC2, AUC1-AUC2 - CI, AUC1-AUC2 + CI, p-value) : tuple
    """

    # determine auc and variance values for both sets
    auc1 = calculate_auc(auc_structure_1, sort_order, 'diff')
    var1a, var1d = calculate_auc_var(auc_structure_1)
    auc2 = calculate_auc(auc_structure_2, sort_order, 'diff')
    var2a, var2d = calculate_auc_var(auc_structure_2)

    # determine covariances between sets
    covara, covard = calculate_auc_covar(auc_structure_1, auc_structure_2)

    # determine standard error
    vardiffa = var2a + var1a - 2 * covara
    vardiffd = var2d + var1a - 2 * covard

    p = len([x for x in auc_structure_1 if x[3] == '1'])
    n = len([x for x in auc_structure_1 if x[3] == '0'])

    se = (vardiffa / p + vardiffd / n) ** 0.5

    # confidence interval
    ci = se * stats.t.ppf(1 - 0.025, n + p - 1)  # 95% confidence interval

    # AUC bounds
    diff = auc1 - auc2
    lower = diff - ci
    upper = diff + ci

    # 2-sided p-value prob(diff >= abs(diff)) = prob(t >= abs(tt))
    # corresponds to the null hypothesis: the two-methods perform identically
    tt = ((diff ** 2) ** 0.5) / se
    p_value = 2 * stats.t.sf(tt, n + p - 1)

    return (auc1, auc2, diff, (lower, upper), p_value)