def aggregate_ant(data, sub_num, response_type="full"):
    """
    Aggregate data from the ANT task.

    Calculates various summary statistics for the ANT task for a given subject.

    Parameters
    ----------
    data : dataframe
        Pandas dataframe containing a single subjects trial data for the task.
    sub_num : str
        Subject number to which the data file belongs.
    response_type : {'full', 'correct', 'incorrect'}, optional
        Should the summary data be calculated using all trials? Only correct 
        trials? Or only incorrect trials? This is not supported in all tasks.

    Returns
    -------
    stats : list
        List containing the calculated data for the subject.
    """

    # Calculate times following errors and correct responses
    df = data
    follow_error_rt = df.loc[df.correct.shift() == 0, "RT"].mean()
    follow_correct_rt = df.loc[df.correct.shift() == 1, "RT"].mean()

    if response_type == "correct":
        df = data[data["correct"] == 1]
    elif response_type == "incorrect":
        df = data[data["correct"] == 0]
    elif response_type == "full":
        df = data

    # Aggregated descriptives

    ## congruency conditions
    grouped_congruency = df.groupby("congruency")
    neutral_rt = grouped_congruency.mean().get_value("neutral", "RT")
    congruent_rt = grouped_congruency.mean().get_value("congruent", "RT")
    incongruent_rt = grouped_congruency.mean().get_value("incongruent", "RT")

    neutral_rtsd = grouped_congruency.std().get_value("neutral", "RT")
    congruent_rtsd = grouped_congruency.std().get_value("congruent", "RT")
    incongruent_rtsd = grouped_congruency.std().get_value("incongruent", "RT")

    neutral_rtcov = neutral_rtsd / neutral_rt
    congruent_rtcov = congruent_rtsd / congruent_rt
    incongruent_rtcov = incongruent_rtsd / incongruent_rt

    neutral_correct = grouped_congruency.sum().get_value("neutral", "correct")
    congruent_correct = grouped_congruency.sum().get_value("congruent", "correct")
    incongruent_correct = grouped_congruency.sum().get_value("incongruent", "correct")

    ## cue conditions
    grouped_cue = df.groupby("cue")
    nocue_rt = grouped_cue.mean().get_value("nocue", "RT")
    center_rt = grouped_cue.mean().get_value("center", "RT")
    spatial_rt = grouped_cue.mean().get_value("spatial", "RT")
    double_rt = grouped_cue.mean().get_value("double", "RT")

    nocue_rtsd = grouped_cue.std().get_value("nocue", "RT")
    center_rtsd = grouped_cue.std().get_value("center", "RT")
    spatial_rtsd = grouped_cue.std().get_value("spatial", "RT")
    double_rtsd = grouped_cue.std().get_value("double", "RT")

    nocue_rtcov = nocue_rtsd / nocue_rt
    center_rtcov = center_rtsd / center_rt
    spatial_rtcov = spatial_rtsd / spatial_rt
    double_rtcov = double_rtsd / double_rt

    nocue_correct = grouped_cue.sum().get_value("nocue", "correct")
    center_correct = grouped_cue.sum().get_value("center", "correct")
    spatial_correct = grouped_cue.sum().get_value("spatial", "correct")
    double_correct = grouped_cue.sum().get_value("double", "correct")

    # OLS regression
    conflict_intercept, conflict_slope = congruent_rt, incongruent_rt - congruent_rt
    conflict_slope_norm = conflict_slope / congruent_rt

    alerting_intercept, alerting_slope = double_rt, nocue_rt - double_rt
    alerting_slope_norm = alerting_slope / double_rt

    orienting_intercept, orienting_slope = spatial_rt, center_rt - spatial_rt
    orienting_slope_norm = orienting_slope / spatial_rt

    return [
        sub_num,
        follow_error_rt,
        follow_correct_rt,
        neutral_rt,
        congruent_rt,
        incongruent_rt,
        neutral_rtsd,
        congruent_rtsd,
        incongruent_rtsd,
        neutral_rtcov,
        congruent_rtcov,
        incongruent_rtcov,
        neutral_correct,
        congruent_correct,
        incongruent_correct,
        nocue_rt,
        center_rt,
        spatial_rt,
        double_rt,
        nocue_rtsd,
        center_rtsd,
        spatial_rtsd,
        double_rtsd,
        nocue_rtcov,
        center_rtcov,
        spatial_rtcov,
        double_rtcov,
        nocue_correct,
        center_correct,
        spatial_correct,
        double_correct,
        conflict_intercept,
        conflict_slope,
        conflict_slope_norm,
        alerting_intercept,
        alerting_slope,
        alerting_slope_norm,
        orienting_intercept,
        orienting_slope,
        orienting_slope_norm,
    ]