def error_estimates(track_file, x_true, t_end, c1, c2):
    print('Starting error estimates (one ship)')
    error_arr = []
    for track_id, state_list in track_file.items():
        error_dic = dict()
        for est in state_list:
            t = est.timestamp
            dist = np.hypot(x_true[0, 0, t] - est.est_posterior[0],
                            x_true[0, 2, t] - est.est_posterior[2])
            error_dic[t] = dist
        error_arr.append(error_dic)

    # Plot
    fig, ax = visualization.setup_plot(None)
    for dic in error_arr:
        list_IPDA = sorted(dic.items())
        xIPDA, yIPDA = zip(*list_IPDA)
        plt.plot(xIPDA, yIPDA)
    ax.set_title('RMSE of 200 runs of 30 scans')
    ax.set_xlabel('Scan number')
    ax.set_ylabel('Distance from real target [m]')
    for axis in [ax.xaxis, ax.yaxis]:
        axis.set_major_locator(ticker.MaxNLocator(integer=True))

    plt.plot((0, t_end), (c1, c1), 'k--')
    plt.plot((0, t_end), (c2, c2), 'k--')
def existence(IPDAF_tracker, IPDAInitiation, track_termination, radar, x_true,
              H, num_ships, time):
    print('Starting existence analysis')
    num_runs = 50
    exist_arr = []
    for run in range(num_runs):
        track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                         track_termination)
        for k, timestamp in enumerate(time):
            measurements = radar.generate_measurements(
                [H.dot(x_true[ship, :, k]) for ship in range(num_ships)],
                timestamp)
            track_manager.step(measurements, timestamp)

        # Existence
        for track_id, state_list in track_manager.track_file.items():
            exist_dic = dict()
            for est in state_list:
                t = est.timestamp
                exist_dic[t] = est.exist_posterior
            exist_arr.append(exist_dic)

    # Plot
    fig, ax = visualization.setup_plot(None)
    for dic in exist_arr:
        list_IPDA = sorted(dic.items())
        xIPDA, yIPDA = zip(*list_IPDA)
        plt.plot(xIPDA, yIPDA)
    ax.set_title('Existence for confirmed tracks')
    ax.set_xlabel('Scan number')
    ax.set_ylabel('Probability')
    ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
def error_distances_plot(IPDAF_tracker, IPDAInitiation, track_termination,
                         x_true, radar, time, H, num_ships, t_end):
    print('Starting error distances plot')
    num_runs = 500
    error_arr = []
    for run in range(num_runs):
        track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                         track_termination)
        # Run tracking
        for k, timestamp in enumerate(time):
            measurements = radar.generate_measurements(
                [H.dot(x_true[ship, :, k]) for ship in range(num_ships)],
                timestamp)
            track_manager.step(measurements, timestamp)

        # Error for estimates (One ship)
        for track_id, state_list in track_manager.track_file.items():
            error_dic = dict()
            for est in state_list:
                t = est.timestamp
                dist = np.hypot(x_true[0, 0, t] - est.est_posterior[0],
                                x_true[0, 2, t] - est.est_posterior[2])
                error_dic[t] = dist
            error_arr.append(error_dic)
        if run % 10 == 0:
            print(run)

    # Plot
    fig, ax = visualization.setup_plot(None)
    for dic in error_arr:
        list_IPDA = sorted(dic.items())
        xIPDA, yIPDA = zip(*list_IPDA)
        plt.plot(xIPDA, yIPDA)
    ax.set_title('Error distance of 500 runs of 30 scans')
    ax.set_xlabel('Scan number')
    ax.set_ylabel('Distance from real target [m]')
    # ax.legend()
    for axis in [ax.xaxis, ax.yaxis]:
        axis.set_major_locator(ticker.MaxNLocator(integer=True))
    c1 = 25
    c2 = 50
    plt.plot((0, t_end), (c1, c1), 'k--')
    plt.plot((0, t_end), (c2, c2), 'k--')
def existence_confirmed_tracks(track_file):
    print('Starting existence of confirmed tracks')
    exist_arr = []
    for track_id, state_list in track_file.items():
        exist_dic = dict()
        for est in state_list:
            t = est.timestamp
            exist_dic[t] = est.exist_posterior
        exist_arr.append(exist_dic)

    # Plot
    fig, ax = visualization.setup_plot(None)
    for dic in exist_arr:
        list_IPDA = sorted(dic.items())
        xIPDA, yIPDA = zip(*list_IPDA)
        plt.plot(xIPDA, yIPDA)
    ax.set_title('Existence for confirmed tracks')
    ax.set_xlabel('Scan number')
    ax.set_ylabel('Probability')
    ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
def roc_test_scenario(P_D, target_model, gate, P_Markov, initiate_thresh,
                      terminate_thresh, spatial_clutter_map):
    np.random.seed(123)

    print('Starting ROC analysis')

    num_runs = 5
    init_values = [0.995, 0.98, 0.95, 0.9, 0.85, 0.8, 0.7, 0.6, 0.51]
    num_IPDA_tests = len(init_values)
    true_IPDA = dict()
    false_IPDA = dict()
    true_IPDA_arr = []
    false_IPDA_arr = []
    init_it = -1
    for para_test in range(num_IPDA_tests):
        init_it += 1
        initiate_thresh = init_values[init_it]
        true_tracks = 0
        false_tracks = 0
        for run in range(num_runs):
            # Run tracking
            IPDAF_tracker = tracking.IPDAFTracker(
                P_D,
                target_model,
                gate,
                P_Markov,
                gate.gamma,
                clutter_map=spatial_clutter_map)
            IPDAInitiation = track_initiation.IPDAInitiation(
                initiate_thresh, terminate_thresh, IPDAF_tracker, gate)
            track_termination = tracking.TrackTerminatorIPDA(terminate_thresh)
            track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                             track_termination)

            true_targets, measurements_all = test_scenario.generate_scenario()
            tracks_checked = set()
            true_targets_detected = set()
            num_false = 0

            for measurements in measurements_all:
                time = list(measurements)[0].timestamp
                track_manager.step(measurements, time)

                new_conf_tracks = [
                    state_list for track_id, state_list in
                    track_manager.track_file.items()
                    if track_id not in tracks_checked
                ]
                for track in new_conf_tracks:
                    [true_track,
                     idx_target] = rmse_criteria_check(track, true_targets)
                    if true_track:
                        if idx_target not in true_targets_detected:
                            true_tracks += 1
                        true_targets_detected.add(idx_target)
                    else:
                        num_false += 1
                [
                    tracks_checked.add(idx)
                    for idx in track_manager.active_tracks
                ]

            false_tracks += min(num_false, 1)

            # Print run number for debugging purposes
            if run % 100 == 0:
                print(
                    "%.1f" % (100 * (run + para_test * num_runs) /
                              (num_IPDA_tests * num_runs)), "% done")

        true_IPDA[initiate_thresh] = (true_tracks / 2.) / num_runs
        false_IPDA[initiate_thresh] = (false_tracks * 1.) / num_runs
        true_IPDA_arr.append(true_IPDA[initiate_thresh])
        false_IPDA_arr.append(false_IPDA[initiate_thresh])

    str_out = ('True IPDA: ' + str(true_IPDA) + '\n\nFalse IPDA: ' +
               str(false_IPDA) + '\n\nArrays:\nTrue IPDA: ' +
               str(true_IPDA_arr) + '\n\nFalse IPDA: ' + str(false_IPDA_arr))

    with codecs.open('./Results/{}.txt'.format('roc_sim'), 'wt',
                     'utf-8') as file:
        file.write(str_out)

    # Plot
    fig, ax = visualization.setup_plot(None)
    plt.semilogy(false_IPDA_arr, true_IPDA_arr, label='IPDA')
    ax.set_title('ROC')
    ax.set_xlabel(r'$P_{FA}$')
    ax.set_ylabel(r'$P_D$')
    ax.legend()
    plt.ylim([0, 1])
    plt.xlim([0, 1])
def roc(P_D, target_model, gate, P_Markov, initiate_thresh, terminate_thresh,
        N_terminate, radar, c2, x_true, H, time):
    print('Starting ROC analysis')
    true_IPDA = dict()
    false_IPDA = dict()
    true_MofN = dict()
    false_MofN = dict()

    num_runs = 2000
    true_IPDA_arr = []
    false_IPDA_arr = []
    true_MofN_arr = []
    false_MofN_arr = []
    init_values = [0.995, 0.98, 0.95, 0.9, 0.85, 0.8, 0.7, 0.6, 0.51]
    # M_values = [8, 7, 6, 6, 5, 4, 4, 3, 3]
    # N_values = [8, 7, 6, 7, 6, 5, 6, 5, 6]
    # M_values = [6, 5, 4, 4, 3, 3]
    # N_values = [6, 6, 5, 6, 5, 6]
    M_values = [4, 3, 3, 2, 2]
    N_values = [4, 3, 4, 2, 3]
    num_IPDA_tests = len(init_values)
    num_MofN_tests = len(M_values)
    for method in range(2):
        init_it = -1
        for para_test in range(num_IPDA_tests if method ==
                               0 else num_MofN_tests):
            init_it += 1
            if method == 0:
                initiate_thresh = init_values[init_it]
            else:
                M_req = M_values[init_it]
                N_test = N_values[init_it]
            true_tracks = 0
            false_tracks = 0
            for run in range(num_runs):
                # Run tracking
                if method == 0:
                    IPDAF_tracker = tracking.IPDAFTracker(
                        P_D, target_model, gate, P_Markov, gate.gamma)
                    IPDAInitiation = track_initiation.IPDAInitiation(
                        initiate_thresh, terminate_thresh, IPDAF_tracker, gate)
                    track_termination = tracking.TrackTerminatorIPDA(
                        terminate_thresh)
                    track_manager = tracking.Manager(IPDAF_tracker,
                                                     IPDAInitiation,
                                                     track_termination)
                else:
                    PDAF_tracker = tracking.PDAFTracker(
                        P_D, target_model, gate)
                    M_of_N = track_initiation.MOfNInitiation(
                        M_req, N_test, PDAF_tracker, gate)
                    track_termination = tracking.TrackTerminatorMofN(
                        N_terminate)
                    track_manager = tracking.Manager(PDAF_tracker, M_of_N,
                                                     track_termination)

                for k, timestamp in enumerate(time):
                    measurements = radar.generate_measurements(
                        [H.dot(x_true[0, :, k])], timestamp)
                    track_manager.step(measurements, timestamp)

                # Check if true tracks have been detected
                num_false = len(track_manager.track_file)
                spotted = 0
                for track_id, state_list in track_manager.track_file.items():
                    true_track = 1
                    for est in state_list:
                        t = est.timestamp
                        dist = np.hypot(x_true[0, 0, t] - est.est_posterior[0],
                                        x_true[0, 2, t] - est.est_posterior[2])
                        if dist > c2:
                            true_track = 0
                            break
                    if true_track == 1:
                        num_false -= 1
                        spotted = 1
                false_tracks += min(num_false, 1)
                true_tracks += spotted

                # Print run number for debugging purposes
                if run % 100 == 0:
                    print(
                        "%.1f" %
                        (100 * (run + para_test * num_runs +
                                method * num_IPDA_tests * num_runs) /
                         ((num_IPDA_tests + num_MofN_tests) * num_runs)),
                        "% done")
            if method == 0:
                true_IPDA[initiate_thresh] = true_tracks / num_runs
                false_IPDA[initiate_thresh] = false_tracks / num_runs
                true_IPDA_arr.append(true_IPDA[initiate_thresh])
                false_IPDA_arr.append(false_IPDA[initiate_thresh])
            else:
                true_MofN[str(M_req) + " of " +
                          str(N_test)] = true_tracks / num_runs
                false_MofN[str(M_req) + " of " +
                           str(N_test)] = false_tracks / num_runs
                true_MofN_arr.append(true_MofN[str(M_req) + " of " +
                                               str(N_test)])
                false_MofN_arr.append(false_MofN[str(M_req) + " of " +
                                                 str(N_test)])

    str_out = ('True IPDA: ' + str(true_IPDA) + '\n\nFalse IPDA: ' +
               str(false_IPDA) + '\n\nTrue MofN: ' + str(true_MofN) +
               '\n\nFalse MofN: ' + str(false_MofN) +
               '\n\nArrays:\nTrue IPDA: ' + str(true_IPDA_arr) +
               '\n\nFalse IPDA: ' + str(false_IPDA_arr) + '\n\nTrue MofN: ' +
               str(true_MofN) + '\n\nFalse MofN: ' + str(false_MofN_arr))

    with codecs.open('./Results/{}.txt'.format('roc_sim'), 'wt',
                     'utf-8') as file:
        file.write(str_out)

    # Plot
    fig, ax = visualization.setup_plot(None)
    plt.plot(false_IPDA_arr, true_IPDA_arr, label='IPDA')
    plt.plot(false_MofN_arr, true_MofN_arr, label='M of N')
    ax.set_title('ROC')
    ax.set_xlabel(r'$P_{FA}$')
    ax.set_ylabel(r'$P_D$')
    ax.legend()
    plt.ylim([0, 1])
    plt.xlim([0, 1])
def false_tracks(P_D, target_model, gate, M_req, N_test, N_terminate,
                 initiate_thresh, terminate_thresh, P_Markov, radar_range, R,
                 time):
    print('Starting false tracks analysis')
    clutter_MofN = dict()
    clutter_IPDA = dict()
    clut_arr = [4e-5, 3.5e-5, 3e-5, 2.5e-5, 2e-5, 1.5e-5, 1e-5, 5e-6]
    for method in range(2):
        clut_it = -1
        for run in range(len(clut_arr)):
            # Run tracking
            if method == 0:
                PDAF_tracker = tracking.PDAFTracker(P_D, target_model, gate)
                M_of_N = track_initiation.MOfNInitiation(
                    M_req, N_test, PDAF_tracker, gate)
                track_termination = tracking.TrackTerminatorMofN(N_terminate)
                track_manager = tracking.Manager(PDAF_tracker, M_of_N,
                                                 track_termination)
            else:
                IPDAF_tracker = tracking.IPDAFTracker(P_D, target_model, gate,
                                                      P_Markov, gate.gamma)
                IPDAInitiation = track_initiation.IPDAInitiation(
                    initiate_thresh, terminate_thresh, IPDAF_tracker, gate)
                track_termination = tracking.TrackTerminatorIPDA(
                    terminate_thresh)
                track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                                 track_termination)

            clut_it += 1
            clutter_density = clut_arr[clut_it]
            print(clutter_density)
            radar = simulation.SquareRadar(radar_range, clutter_density, P_D,
                                           R)
            for k, timestamp in enumerate(time):
                measurements = radar.generate_clutter_measurements(timestamp)
                track_manager.step(measurements, timestamp)
                if k % 50 == 0:
                    print(len(track_manager.track_file))
            if method == 0:
                clutter_MofN[clutter_density] = len(track_manager.track_file)
            else:
                clutter_IPDA[clutter_density] = len(track_manager.track_file)

    list_MofN = sorted(clutter_MofN.items())
    list_IPDA = sorted(clutter_IPDA.items())
    xMofN, yMofN = zip(*list_MofN)
    xIPDA, yIPDA = zip(*list_IPDA)

    str_out = ('Densities IPDA: ' + str(xIPDA) + '\n\nFalse tracks IPDA: ' +
               str(yIPDA) + '\n\nDensities MofN: ' + str(xMofN) +
               '\n\nFalse tracks MofN: ' + str(yMofN))

    with codecs.open('./Results/{}.txt'.format('false_tracks_sim'), 'wt',
                     'utf-8') as file:
        file.write(str_out)

    # Plot
    fig, ax = visualization.setup_plot(None)
    plt.semilogy(xMofN, yMofN, '--', label='M of N')
    plt.semilogy(xIPDA, yIPDA, label='IPDA')
    ax.set_title('False tracks detected over 1000 scans')
    ax.set_xlabel('Clutter density')
    ax.set_ylabel('False tracks detected')
    plt.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    ax.legend()
def rmse(P_D, target_model, gate, initiate_thresh, terminate_thresh, P_Markov,
         time, x_true, H, num_ships, radar, c2):
    print('Starting RMSE analysis')
    errors_IPDA = dict()
    num_runs = 100
    for run in range(num_runs):
        # Run tracking
        IPDAF_tracker = tracking.IPDAFTracker(P_D, target_model, gate,
                                              P_Markov, gate.gamma)
        IPDAInitiation = track_initiation.IPDAInitiation(
            initiate_thresh, terminate_thresh, IPDAF_tracker, gate)
        track_termination = tracking.TrackTerminatorIPDA(terminate_thresh)
        track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                         track_termination)

        for k, timestamp in enumerate(time):
            measurements = radar.generate_measurements(
                [H.dot(x_true[ship, :, k]) for ship in range(num_ships)],
                timestamp)
            track_manager.step(measurements, timestamp)

            # Check if true tracks have been detected
            for track_id, state_list in track_manager.track_file.items():
                states = np.array([est.est_posterior for est in state_list])
                for ship in range(num_ships):
                    dist = np.hypot(x_true[ship, 0, k] - states[-1, 0],
                                    x_true[ship, 2, k] - states[-1, 2])
                    if dist < c2:
                        if k + 1 in errors_IPDA:
                            errors_IPDA[k + 1].append(dist)
                        else:
                            errors_IPDA[k + 1] = [dist]

        # Print time for debugging purposes
        if run % 50 == 0:
            print("%.1f" % (100 * run / num_runs), "% done")

    for scan in errors_IPDA:
        errors_IPDA[scan] = sum(errors_IPDA[scan]) / len(errors_IPDA[scan])

    maxValue = max(errors_IPDA.values())
    maxKey = max(errors_IPDA.keys())

    list_IPDA = sorted(errors_IPDA.items())
    xIPDA, yIPDA = zip(*list_IPDA)
    print("scan numbers: ", xIPDA)
    print("Distances: ", yIPDA)

    str_out = ('Scan numbers: ' + str(xIPDA) + '\n\nDistances: ' + str(yIPDA))

    with codecs.open('./Results/{}.txt'.format('rmse_sim'), 'wt',
                     'utf-8') as file:
        file.write(str_out)

    # Plot
    fig, ax = visualization.setup_plot(None)
    plt.plot(xIPDA, yIPDA, label='IPDA')
    ax.set_title('RMSE of 10 000 runs of 30 scans')
    ax.set_xlabel('Scan number')
    ax.set_ylabel('Distance from real target [m]')
    ax.legend()
    for axis in [ax.xaxis, ax.yaxis]:
        axis.set_major_locator(ticker.MaxNLocator(integer=True))
    plt.ylim([0, maxValue])
    plt.xlim([1, maxKey])
def true_tracks(PDAF_tracker, M_of_N, IPDAF_tracker, IPDAInitiation,
                N_terminate, terminate_thresh, time, x_true, num_ships, H,
                radar, c2):
    print('Starting true tracks analysis')
    scans_MofN = dict()
    scans_IPDA = dict()
    num_runs = 500
    for method in range(2):
        for run in range(num_runs):
            # Run tracking
            if method == 0:
                track_termination = tracking.TrackTerminatorMofN(N_terminate)
                track_manager = tracking.Manager(PDAF_tracker, M_of_N,
                                                 track_termination)
            else:
                track_termination = tracking.TrackTerminatorIPDA(
                    terminate_thresh)
                track_manager = tracking.Manager(IPDAF_tracker, IPDAInitiation,
                                                 track_termination)

            tracks_spotted = set()
            for k, timestamp in enumerate(time):
                measurements = radar.generate_measurements(
                    [H.dot(x_true[ship, :, k]) for ship in range(num_ships)],
                    timestamp)
                track_manager.step(measurements, timestamp)

                # Check if true tracks have been detected
                for track_id, state_list in track_manager.track_file.items():
                    states = np.array(
                        [est.est_posterior for est in state_list])
                    for ship in range(num_ships):
                        if np.hypot(x_true[ship, 0, k] - states[-1, 0],
                                    x_true[ship, 2, k] - states[-1, 2]) < c2:
                            tracks_spotted.add(ship)
                            break
                if len(tracks_spotted) == num_ships:
                    if method == 0:
                        if k + 1 in scans_MofN:
                            scans_MofN[k + 1] += 1
                        else:
                            scans_MofN[k + 1] = 1
                    else:
                        if k + 1 in scans_IPDA:
                            scans_IPDA[k + 1] += 1
                        else:
                            scans_IPDA[k + 1] = 1
                    break

            # Print time for debugging purposes
            if run % 50 == 0:
                print(run)

    max_key = max(max(scans_MofN.keys()), max(scans_IPDA.keys()))

    for scans in [scans_MofN, scans_IPDA]:
        for key in range(1, max_key + 1):
            if key not in scans:
                scans[key] = 0

        last = 0
        for key in sorted(scans.keys()):
            last = last + scans[key]
            scans[key] = last

    list_MofN = sorted(scans_MofN.items())
    list_IPDA = sorted(scans_IPDA.items())
    xMofN, yMofN = zip(*list_MofN)
    xIPDA, yIPDA = zip(*list_IPDA)

    # Plot
    fig, ax = visualization.setup_plot(None)
    plt.plot(xMofN, yMofN, '--', label='M of N')
    plt.plot(xIPDA, yIPDA, label='IPDA')
    ax.set_title('True detected tracks out of 500')
    ax.set_xlabel('Scans needed')
    ax.set_ylabel('Detected tracks')
    ax.legend()
    # ax.grid()
    for axis in [ax.xaxis, ax.yaxis]:
        axis.set_major_locator(ticker.MaxNLocator(integer=True))
    # plt.xlim([1, 20])
    plt.ylim([0, 500])