Exemplo n.º 1
0
def localize_pysf(rel_sounds,
                  r_locs,
                  invert_alg='gps',
                  center_array=True,
                  use_sos_selection=False,
                  temperature=20.0):
    '''
    Use PySoundFinder to localize many sounds
    
    Inputs:
        rel_sounds (pandas DF): relative TOAs of sounds
            columns are recorder names
            rows are sound indices
        r_locs (pandas DF): recorder locations
            columns are x, y, and optionally, z
            rows are recorder names as in rel_sounds
        invert_alg: algorithm to invert matrix (see pysoundfinder)
        center_array (bool): whether to center array coordinates
            for computational stability prior to localizing sounds
        use_sos_selection (bool): whether to select solution
            based on sum of squares (original Sound Finder behavior)
        temperature (float): temperature in Celsius
    '''

    # Localize sounds in rel_sounds
    localized = []
    for sound_num in rel_sounds.index:
        delays = rel_sounds.T[sound_num]

        localized.append(
            pysf.localize_sound(positions=r_locs,
                                times=delays,
                                temp=temperature,
                                invert_alg='gps',
                                center=center_array,
                                pseudo=not use_sos_selection))

    # Return dataframe in desired format
    # TODO: Currently, reshape is necessary in 3D case to bring results
    # into an (A, B) shaped matrix instead of an (A, B, 1) shaped matrix.
    # This doesn't happen in 2D case. Worth inspecting. This try/except is a quick patch.
    try:
        df = pd.DataFrame(np.array(localized).reshape(rel_sounds.shape),
                          index=rel_sounds.index)
    except ValueError:
        return localized
    if df.shape[1] == 4:
        df.columns = ['x', 'y', 'z', 'r']
    elif df.shape[1] == 3:
        df.columns = ['x', 'y', 'r']
    else:
        print('Warning: results are not expected dimension (3 or 4 columns)')
    return df
Exemplo n.º 2
0
def test_localize_3d_grid(simulated_times_df):
    '''
    Test pysf.localize_sound for a 3d grid of points
    on a 30m^2 x 16m high plot. Asserts accuracy to 
    4 decimals in each coordinate.
    
    Note: sounds with one component exactly at 0 
    aren't localized well for 4 recorders perfectly 
    at the corners of a 30x30 plot. This is a highly 
    unlikely situation, though; even a 0.01m
    offset is enough for near perfect localization.
    
    Also note that if all of the recorders are on 
    the same plane, 3D localization fails frequently.
    Even a +- 0.2m difference in recorder heights is
    enough for highly accurate localization.
    '''

    recorder_list = [(0, 0, 3), (0, 30, 3.2), (30, 0, 3.3), (30, 30, 3.4)]
    temp_c = 20.0
    grid_points = [(x, y, z) for x in np.arange(0.01, 30, 2)
                   for y in np.arange(0.01, 30, 2)
                   for z in np.arange(0.01, 15, 2)]

    failed_list = []

    for point in grid_points:
        true_position = point

        positions, times, temps = simulated_times_df(sound=true_position,
                                                     recorders=recorder_list,
                                                     temp=temp_c)

        [x, y, z, s] = pysf.localize_sound(positions, times, temps.temp)

        est_position = (x[0], y[0], z[0])

        try:
            npt.assert_almost_equal(est_position, true_position, decimal=4)
        except AssertionError:
            failed_list.append((true_position, est_position))

    # Print information about the failures if the failed_list contains anything
    for i, failure in enumerate(failed_list):
        pass
        print("Failure {}:".format(i + 1))
        print("  True position: {} ".format(failure[0]))
        print("  Estimated position: {} ".format(failure[1]))
    print("Number failed: {}".format(len(failed_list)))
    assert (len(failed_list) == 0)
Exemplo n.º 3
0
def test_localize_3d(simulated_times_df):
    '''
    Test pysf.localize_sound() for sound at (4, 2, 20).
    Asserts accuracy to 6 decimals in each coordinate.
    '''

    recorder_list = [(0, 0, 2), (0, 30, 3), (30, 0, 3), (30, 30, 3.0)]
    true_position = (4, 2, 20)
    temp_c = 20.0

    positions, times, temps = simulated_times_df(sound=true_position,
                                                 recorders=recorder_list,
                                                 temp=temp_c)

    [x, y, z, s] = pysf.localize_sound(positions, times, temps.temp)

    est_position = [x[0], y[0], z[0]]

    npt.assert_almost_equal(est_position, true_position, decimal=6)
Exemplo n.º 4
0
def test_localizing_grid_with_6_recorders(simulated_times_df):
    '''
    Ensure that pysf can localize a grid of points
    using 6 delays. Asserts accuracy to 6 decimals in each coordinate.
    '''

    recorder_list = [(0, 0), (0, 30), (30, 0), (30, 30), (40, 40), (-10, 5)]
    temp_c = 18
    grid_points = [(x, y) for x in range(-10, 40, 2)
                   for y in range(-10, 40, 2)]

    failed_list = []

    # Simulate localization of each point in the grid
    for true_position in grid_points:

        print(true_position)

        positions, times, temps = simulated_times_df(sound=true_position,
                                                     recorders=recorder_list,
                                                     temp=temp_c)

        [x, y, s] = pysf.localize_sound(positions, times, temps.temp)

        est_position = [x[0], y[0]]

        try:
            npt.assert_almost_equal(est_position, true_position, decimal=6)
        except AssertionError:
            failed_list.append((true_position, est_position))

    # Print information about the failures if the failed_list contains anything
    for i, failure in enumerate(failed_list):
        print("Failure {}:".format(i + 1))
        print("  True position: {} ".format(failure[0]))
        print("  Estimated position: {} ".format(failure[1]))

    assert (len(failed_list) == 0)
Exemplo n.º 5
0
def test_localize_2d_grid(simulated_times_df):
    '''
    Test pysf.localize_sound for a 2d grid of points
    on and around a 30m^2 plot. Asserts accuracy to 
    6 decimals in each coordinate.
    '''

    recorder_list = [(0, 0), (0, 30), (30, 0), (30, 30)]
    temp_c = 20.0
    grid_points = [(x, y) for x in range(-10, 40, 2)
                   for y in range(-10, 40, 2)]

    failed_list = []

    for point in grid_points:
        true_position = point

        positions, times, temps = simulated_times_df(sound=true_position,
                                                     recorders=recorder_list,
                                                     temp=temp_c)

        [x, y, s] = pysf.localize_sound(positions, times, temps.temp)

        est_position = [x[0], y[0]]

        try:
            npt.assert_almost_equal(est_position, true_position, decimal=6)
        except AssertionError:
            failed_list.append((true_position, est_position))

    # Print information about the failures if the failed_list contains anything
    for i, failure in enumerate(failed_list):
        print("Failure {}:".format(i + 1))
        print("  True position: {} ".format(failure[0]))
        print("  Estimated position: {} ".format(failure[1]))

    assert (len(failed_list) == 0)