示例#1
0
文件: common.py 项目: nkeim/trackpy
def assert_traj_equal(actual, expected, pos_atol=1):
    assert_equal(len(actual), len(expected))
    actual = pandas_sort(actual, 'frame').reset_index(drop=True)
    expected = pandas_sort(expected, 'frame').reset_index(drop=True)
    actual_order = []
    for frame_no in expected['frame'].unique():
        actual_f = actual[actual['frame'] == frame_no]
        expected_f = expected[expected['frame'] == frame_no]
        assert_equal(len(actual_f), len(expected_f),
                     err_msg='Actual and expected numbers of features '
                             'differ in frame %i' % frame_no)
        tree = cKDTree(actual_f[['y', 'x']].values)
        devs, argsort = tree.query(expected_f[['y', 'x']].values)
        assert_allclose(devs, 0., atol=pos_atol)
        actual_order.extend(actual_f.index[argsort].tolist())

    actual = actual.loc[actual_order].reset_index(drop=True, inplace=False)
    for p_actual in actual.particle.unique():
        actual_ind = actual.index[actual['particle'] == p_actual]
        p_expected = expected.loc[actual_ind[0], 'particle']
        expected_ind = expected.index[expected['particle'] == p_expected]
        assert_array_equal(actual_ind, expected_ind,
                           err_msg='Actual and expected linking results '
                           'differ for actual particle %i/expected particle %i'
                           '' % (p_actual, p_expected))
示例#2
0
def sort_positions(actual, expected):
    tree = cKDTree(actual)
    deviations, argsort = tree.query([expected])
    if len(set(range(len(actual))) - set(argsort[0])) > 0:
        raise AssertionError("Position sorting failed. At least one feature is "
                             "very far from where it should be.")
    return deviations, actual[argsort][0]
示例#3
0
def assert_traj_equal(actual, expected, pos_atol=1):
    assert_equal(len(actual), len(expected))
    actual = pandas_sort(actual, 'frame').reset_index(drop=True)
    expected = pandas_sort(expected, 'frame').reset_index(drop=True)
    actual_order = []
    for frame_no in expected['frame'].unique():
        actual_f = actual[actual['frame'] == frame_no]
        expected_f = expected[expected['frame'] == frame_no]
        assert_equal(len(actual_f),
                     len(expected_f),
                     err_msg='Actual and expected numbers of features '
                     'differ in frame %i' % frame_no)
        tree = cKDTree(actual_f[['y', 'x']].values)
        devs, argsort = tree.query(expected_f[['y', 'x']].values)
        assert_allclose(devs, 0., atol=pos_atol)
        actual_order.extend(actual_f.index[argsort].tolist())

    actual = actual.loc[actual_order].reset_index(drop=True, inplace=False)
    for p_actual in actual.particle.unique():
        actual_ind = actual.index[actual['particle'] == p_actual]
        p_expected = expected.loc[actual_ind[0], 'particle']
        expected_ind = expected.index[expected['particle'] == p_expected]
        assert_array_equal(actual_ind,
                           expected_ind,
                           err_msg='Actual and expected linking results '
                           'differ for actual particle %i/expected particle %i'
                           '' % (p_actual, p_expected))
示例#4
0
def sort_positions(actual, expected):
    tree = cKDTree(actual)
    deviations, argsort = tree.query([expected])
    if len(set(range(len(actual))) - set(argsort[0])) > 0:
        raise AssertionError(
            "Position sorting failed. At least one feature is "
            "very far from where it should be.")
    return deviations, actual[argsort][0]
示例#5
0
def eliminate_overlapping_locations(f, separation):
    """ Makes sure that no position is within `separation` from each other, by
    deleting one of the that are to close to each other.
    """
    separation = validate_tuple(separation, f.shape[1])
    assert np.greater(separation, 0).all()
    # Rescale positions, so that pairs are identified below a distance of 1.
    f = f / separation
    while True:
        duplicates = cKDTree(f, 30).query_pairs(1)
        if len(duplicates) == 0:
            break
        to_drop = []
        for pair in duplicates:
            to_drop.append(pair[1])
        f = np.delete(f, to_drop, 0)
    return f * separation
示例#6
0
def eliminate_overlapping_locations(f, separation):
    """ Makes sure that no position is within `separation` from each other, by
    deleting one of the that are to close to each other.
    """
    separation = validate_tuple(separation, f.shape[1])
    assert np.greater(separation, 0).all()
    # Rescale positions, so that pairs are identified below a distance of 1.
    f = f / separation
    while True:
        duplicates = cKDTree(f, 30).query_pairs(1)
        if len(duplicates) == 0:
            break
        to_drop = []
        for pair in duplicates:
            to_drop.append(pair[1])
        f = np.delete(f, to_drop, 0)
    return f * separation
示例#7
0
def compare_pos_df(actual, expected, pos_atol=0.001, lost_atol=1):
    """Returns indices of equal and different positions inside dataframes
    `actual` and `expected`."""
    lost0 = []
    appeared1 = []
    dev0 = []
    dev1 = []
    equal0 = []
    equal1 = []
    for frame_no, expected_frame in expected.groupby('frame'):
        coords0 = expected_frame[['y', 'x']].values
        actual_frame = actual[actual['frame'] == frame_no]
        coords1 = actual_frame[['y', 'x']].values

        # use a KDTree to find nearest neighbors
        tree = cKDTree(coords1)
        devs, inds = tree.query(coords0)  # find nearest neighbors

        i_lost0 = np.argwhere(devs > lost_atol).ravel()
        # features that are equal
        i_equal0 = np.argwhere(devs < pos_atol).ravel()
        i_equal1 = inds[i_equal0]
        # features that are the same, but deviate in position
        i_dev0 = np.argwhere((devs < lost_atol) & (devs >= pos_atol)).ravel()
        i_dev1 = inds[i_dev0]
        # features that present in f1 and not in f0
        i_appeared1 = np.argwhere(~np.in1d(np.arange(len(coords1)),
                                           np.concatenate(
                                               [i_equal0, i_dev0]))).ravel()
        lost0.append(pandas_iloc(expected_frame, i_lost0).index.values)
        appeared1.append(pandas_iloc(actual_frame, i_appeared1).index.values)
        dev0.append(pandas_iloc(expected_frame, i_dev0).index.values)
        dev1.append(pandas_iloc(actual_frame, i_dev1).index.values)
        equal0.append(pandas_iloc(expected_frame, i_equal0).index.values)
        equal1.append(pandas_iloc(actual_frame, i_equal1).index.values)

    return np.concatenate(lost0), np.concatenate(appeared1), \
           (np.concatenate(dev0), np.concatenate(dev1)), \
           (np.concatenate(equal0), np.concatenate(equal1)),
示例#8
0
def compare_pos_df(actual, expected, pos_atol=0.001, lost_atol=1):
    """Returns indices of equal and different positions inside dataframes
    `actual` and `expected`."""
    lost0 = []
    appeared1 = []
    dev0 = []
    dev1 = []
    equal0 = []
    equal1 = []
    for frame_no, expected_frame in expected.groupby('frame'):
        coords0 = expected_frame[['y', 'x']].values
        actual_frame = actual[actual['frame'] == frame_no]
        coords1 = actual_frame[['y', 'x']].values

        # use a KDTree to find nearest neighbors
        tree = cKDTree(coords1)
        devs, inds = tree.query(coords0)  # find nearest neighbors

        i_lost0 = np.argwhere(devs > lost_atol).ravel()
        # features that are equal
        i_equal0 = np.argwhere(devs < pos_atol).ravel()
        i_equal1 = inds[i_equal0]
        # features that are the same, but deviate in position
        i_dev0 = np.argwhere((devs < lost_atol) & (devs >= pos_atol)).ravel()
        i_dev1 = inds[i_dev0]
        # features that present in f1 and not in f0
        i_appeared1 = np.argwhere(~np.in1d(np.arange(len(coords1)),
                                           np.concatenate(
                                               [i_equal0, i_dev0]))).ravel()
        lost0.append(pandas_iloc(expected_frame, i_lost0).index.values)
        appeared1.append(pandas_iloc(actual_frame, i_appeared1).index.values)
        dev0.append(pandas_iloc(expected_frame, i_dev0).index.values)
        dev1.append(pandas_iloc(actual_frame, i_dev1).index.values)
        equal0.append(pandas_iloc(expected_frame, i_equal0).index.values)
        equal1.append(pandas_iloc(actual_frame, i_equal1).index.values)

    return np.concatenate(lost0), np.concatenate(appeared1), \
           (np.concatenate(dev0), np.concatenate(dev1)), \
           (np.concatenate(equal0), np.concatenate(equal1)),
示例#9
0
def _find_pairs(pos, max_dist, max_dist_3):
    """Determine isolated pairs of particles: closer than ``max_dist`` together
    with a possible third particle farther than ``max_dist_3`` from any of them.

    Optimal for few features. Should use cKDTree or something else for many
    features

    Returns array of pair indices (shape N x 2)"""
    # matrix of all combinations
    pos = np.atleast_2d(pos)
    kdt = cKDTree(pos)
    sparse_mat = kdt.sparse_distance_matrix(kdt, max_distance=max_dist)
    dist = dist_eucl(pos[..., np.newaxis], pos[np.newaxis, ...])
    compare_3 = (dist <= max_dist_3).sum(0)

    # particles having 0 neighbors closer than the three-body limit
    # they are free to pair with any particle from this list
    neighbors_0 = np.where(compare_3 == 1)[0]
    if len(neighbors_0) > 1:
        dist_masked = dist[neighbors_0][:, neighbors_0]
        pairs_0 = np.nonzero(np.tril(dist_masked <= max_dist, k=-1))
    else:
        pairs_0 = ([], [])
    pairs_0 = [neighbors_0[ind] for ind in pairs_0]

    # particles having 1 neighbor closer than the three-body limit
    # this neighbor is directly the pair
    neighbors_1 = np.where(compare_3 == 2)[0]
    if len(neighbors_1) > 1:
        dist_masked = dist[neighbors_1][:, neighbors_1]
        pairs_1 = np.nonzero(np.tril(dist_masked <= max_dist_3, k=-1))
    else:
        pairs_1 = ([], [])
    pairs_1 = [neighbors_1[ind] for ind in pairs_1]
    pairs = np.concatenate([pairs_0, pairs_1], axis=1)
    pairs_dist = dist[pairs[0], pairs[1]]
    return pairs.T, pairs_dist