예제 #1
0
def test_orientations_from_view_up():
    """Create `Orientations` from view and up vectors."""
    # test with single view and up vectors
    view = [1, 0, 0]
    up = [0, 1, 0]
    Orientations.from_view_up(view, up)
    # test with multiple view and up vectors
    views = [[1, 0, 0], [0, 0, 1]]
    ups = [[0, 1, 0], [0, 1, 0]]
    Orientations.from_view_up(views, ups)
    # provided as numpy ndarrays
    views = np.atleast_2d(views).astype(np.float64)
    ups = np.atleast_2d(ups).astype(np.float64)
    Orientations.from_view_up(views, ups)
    # provided as Coordinates
    views = Coordinates(views[:, 0], views[:, 1], views[:, 2])
    ups = Coordinates(ups[:, 0], ups[:, 1], ups[:, 2])
    Orientations.from_view_up(views, ups)
    # number of views to ups N:1
    views = [[1, 0, 0], [0, 0, 1]]
    ups = [[0, 1, 0]]
    Orientations.from_view_up(views, ups)
    # number of views to ups 1:N
    views = [[1, 0, 0]]
    ups = [[0, 1, 0], [0, 1, 0]]
    Orientations.from_view_up(views, ups)
    # number of views to ups M:N
    with raises(ValueError):
        views = [[1, 0, 0], [0, 0, 1], [0, 0, 1]]
        ups = [[0, 1, 0], [0, 1, 0]]
        Orientations.from_view_up(views, ups)
예제 #2
0
def test_getter_with_degrees():
    """Test if getter return correct values also in degrees"""
    coords = Coordinates(0, 1, 0)

    sph = coords.get_sph(unit="deg")
    npt.assert_allclose(sph, np.atleast_2d([90, 90, 1]))

    cyl = coords.get_cyl(unit="deg")
    npt.assert_allclose(cyl, np.atleast_2d([90, 0, 1]))
예제 #3
0
def test_coordinates_init_default_convention_and_unit():
    """Test initialization with the default convention and untit."""
    # get list of available coordinate systems
    coords = Coordinates()
    systems = coords._systems()

    # test constructor with all systems, units, and convention=None
    for domain in systems:
        Coordinates(0, 0, 0, domain)
예제 #4
0
def test_coordinates_init_val_and_weights():
    """Test initialization with weights."""
    # correct number of weights
    coords = Coordinates([1, 2], 0, 0, weights=[.5, .5])
    assert isinstance(coords, Coordinates)
    npt.assert_allclose(coords.weights, [.5, .5])

    # incorrect number of weights
    with raises(AssertionError):
        Coordinates([1, 2], 0, 0, weights=.5)
예제 #5
0
def test_getitem():
    """Test getitem with different parameters."""
    # test without weights
    coords = Coordinates([1, 2], 0, 0)
    new = coords[0]
    assert isinstance(new, Coordinates)
    npt.assert_allclose(new.get_cart(), np.atleast_2d([1, 0, 0]))

    # test with weights
    coords = Coordinates([1, 2], 0, 0, weights=[.1, .9])
    new = coords[0]
    assert isinstance(new, Coordinates)
    npt.assert_allclose(new.get_cart(), np.atleast_2d([1, 0, 0]))
    assert new.weights == np.array(.1)

    # test with 3D array
    coords = Coordinates([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6]], 0, 0)
    new = coords[0:1]
    assert isinstance(new, Coordinates)
    assert new.cshape == (1, 5)

    # test if sliced object stays untouched
    coords = Coordinates([0, 1], [0, 1], [0, 1])
    new = coords[0]
    new.set_cart(2, 2, 2)
    assert coords.cshape == (2, )
    npt.assert_allclose(coords.get_cart()[0], np.array([0, 0, 0]))
예제 #6
0
def test_csize():
    """Test the csize attribute."""
    # 0 points
    coords = Coordinates()
    assert coords.csize == 0
    # two points
    coords = Coordinates([1, 0], 1, 1)
    assert coords.csize == 2
    # 6 points in two dimensions
    coords = Coordinates([[1, 2, 3], [4, 5, 6]], 1, 1)
    assert coords.csize == 6
예제 #7
0
def test_cdim():
    """Test the csim attribute."""
    # empty
    coords = Coordinates()
    assert coords.cdim == 0
    # 2D points
    coords = Coordinates([1, 0], 1, 1)
    assert coords.cdim == 1
    # 3D points
    coords = Coordinates([[1, 2, 3], [4, 5, 6]], 1, 1)
    assert coords.cdim == 2
예제 #8
0
def test_cshape():
    """Test the cshape attribute."""
    # empty
    coords = Coordinates()
    assert coords.cshape == (0, )
    # 2D points
    coords = Coordinates([1, 0], [1, 1], [0, 1])
    assert coords.cshape == (2, )
    # 3D points
    coords = Coordinates([[1, 2, 3], [4, 5, 6]], 1, 1)
    assert coords.cshape == (2, 3)
예제 #9
0
def test_coordinates_init_default_convention():
    """Test initialization with the default convention."""
    # get list of available coordinate systems
    coords = Coordinates()
    systems = coords._systems()

    # test constructor with all systems, units, and convention=None
    for domain in systems:
        convention = list(systems[domain])[0]
        for unit in systems[domain][convention]['units']:
            Coordinates(0, 0, 0, domain, unit=unit[0][0:3])
예제 #10
0
def test___eq___differInUnit_notEqual():
    coordinates = Coordinates([1, 1], [1, 1], [1, 1],
                              convention='top_colat',
                              domain='sph',
                              unit='rad')
    actual = Coordinates([1, 1], [1, 1], [1, 1],
                         convention='top_colat',
                         domain='sph',
                         unit='deg')
    is_equal = coordinates == actual
    assert not is_equal
예제 #11
0
def test_coordinates_init_val_and_system():
    """Test initialization with all available coordinate systems."""
    # get list of available coordinate systems
    coords = Coordinates()
    systems = coords._systems()

    # test constructor with all systems
    for domain in systems:
        for convention in systems[domain]:
            for unit in systems[domain][convention]['units']:
                Coordinates(0, 0, 0, domain, convention, unit[0][0:3])
예제 #12
0
def test_show():
    """Test if possible calls of show() pass."""
    coords = Coordinates([-1, 0, 1], 0, 0)
    # show without mask
    coords.show()
    # show with mask as list
    coords.show([1, 0, 1])
    # show with mask as ndarray
    coords.show(np.array([1, 0, 1], dtype=bool))
    # test assertion
    with raises(AssertionError):
        coords.show(np.array([1, 0], dtype=bool))

    plt.close("all")
예제 #13
0
def test_setter_and_getter_with_conversion():
    """Test conversion between coordinate systems using the default unit."""
    # get list of available coordinate systems
    coords = Coordinates()
    systems = coords._systems()
    # test points contained in system definitions
    points = [
        'positive_x', 'positive_y', 'positive_z', 'negative_x', 'negative_y',
        'negative_z'
    ]

    # test setter and getter with all systems and default unit
    for domain_in in list(systems):
        for convention_in in list(systems[domain_in]):
            for domain_out in list(systems):
                for convention_out in list(systems[domain_out]):
                    for point in points:
                        # for debugging
                        print(f"{domain_in}({convention_in}) -> "
                              f"{domain_out}({convention_out}): {point}")
                        # in and out points
                        p_in = systems[domain_in][convention_in][point]
                        p_out = systems[domain_out][convention_out][point]
                        # empty object
                        c = Coordinates()
                        # --- set point ---
                        eval(f"c.set_{domain_in}(p_in[0], p_in[1], p_in[2], \
                             '{convention_in}')")
                        # check point
                        p = c._points
                        npt.assert_allclose(p.flatten(), p_in, atol=1e-15)
                        # --- test without conversion ---
                        p = eval(f"c.get_{domain_out}('{convention_out}')")
                        # check internal and returned point
                        npt.assert_allclose(c._points.flatten(),
                                            p_in,
                                            atol=1e-15)
                        npt.assert_allclose(p.flatten(), p_out, atol=1e-15)
                        # check if system was converted
                        assert c._system["domain"] == domain_in
                        assert c._system["convention"] == convention_in
                        # --- test with conversion ---
                        p = eval(f"c.get_{domain_out}('{convention_out}', \
                                 convert=True)")
                        # check point
                        npt.assert_allclose(p.flatten(), p_out, atol=1e-15)
                        # check if system was converted
                        assert c._system["domain"] == domain_out
                        assert c._system["convention"] == convention_out
예제 #14
0
def sphericalvoronoi():
    """ SphericalVoronoi object.
    """
    points = np.array([[0, 0, 1], [0, 0, -1], [1, 0, 0], [0, 1, 0], [0, -1, 0],
                       [-1, 0, 0]])
    sampling = Coordinates(points[:, 0], points[:, 1], points[:, 2])
    return SphericalVoronoi(sampling)
예제 #15
0
 def _decode(cls, obj_dict):
     """Decode object based on its respective `_encode` counterpart."""
     sampling = Coordinates(obj_dict['points'][:, 0],
                            obj_dict['points'][:, 1],
                            obj_dict['points'][:, 2],
                            domain='cart')
     return cls(sampling, center=obj_dict['center'])
예제 #16
0
def test_assertion_for_getter():
    """Test assertion for empty Coordinates objects"""
    coords = Coordinates()
    with raises(ValueError, match="Object is empty"):
        coords.get_cart()
    with raises(ValueError, match="Object is empty"):
        coords.get_sph()
    with raises(ValueError, match="Object is empty"):
        coords.get_cyl()
예제 #17
0
def test_coordinate_names():
    """Test if units agree across coordinates that appear more than once"""

    # get all coordinate systems
    c = Coordinates()
    systems = c._systems()

    # get unique list of coordinates and their properties
    coords = {}
    # loop across domains and conventions
    for domain in systems:
        for convention in systems[domain]:
            # loop across coordinates
            for cc, coord in enumerate(
                    systems[domain][convention]['coordinates']):
                # units of the current coordinate
                cur_units = [
                    u[cc] for u in systems[domain][convention]['units']
                ]
                # add coordinate to coords
                if coord not in coords:
                    coords[coord] = {}
                    coords[coord]['domain'] = [domain]
                    coords[coord]['convention'] = [convention]
                    coords[coord]['units'] = [cur_units]
                else:
                    coords[coord]['domain'].append(domain)
                    coords[coord]['convention'].append(convention)
                    coords[coord]['units'].append(cur_units)

    # check if units agree across coordinates that appear more than once
    for coord in coords:
        # get unique first entry
        units = coords[coord]['units'].copy()
        units_ref, idx = np.unique(units[0], True)
        units_ref = units_ref[idx]
        for cc in range(1, len(units)):
            # get next entry for comparison
            units_test, idx = np.unique(units[cc], True)
            units_test = units_test[idx]
            # compare
            assert all(units_ref == units_test), \
                f"'{coord}' has units {units_ref} in "\
                f"{coords[coord]['domain'][0]} "\
                f"({coords[coord]['convention'][0]}) but units {units_test} "\
                f"in {coords[coord]['domain'][cc]} "\
                f"({coords[coord]['convention'][cc]})"
예제 #18
0
def test_inverse_rotation():
    """Test the inverse rotation."""
    xyz = np.concatenate((np.ones((2, 4, 1)), np.zeros(
        (2, 4, 1)), np.zeros((2, 4, 1))), -1)
    c = Coordinates(xyz[..., 0].copy(), xyz[..., 1].copy(), xyz[..., 2].copy())
    c.rotate('z', 90)
    c.rotate('z', 90, inverse=True)
    npt.assert_allclose(c.get_cart(), xyz, atol=1e-15)
예제 #19
0
def test__systems():
    """Test completeness of internal representation of coordinate systems."""

    # get all coordinate systems
    coords = Coordinates()
    systems = coords._systems()

    # check object type
    assert isinstance(systems, dict)

    # check completeness of systems
    for domain in systems:
        for convention in systems[domain]:
            assert "description_short" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'description_short'"
            assert "coordinates" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'coordinates'"
            assert "units" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'units'"
            assert "description" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'description'"
            assert "positive_x" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'positive_x'"
            assert "positive_y" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'positive_y'"
            assert "negative_x" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'negative_'"
            assert "negative_y" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'negative_y'"
            assert "positive_z" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'positive_z'"
            assert "negative_z" in systems[domain][convention], \
                f"{domain} ({convention}) is missing entry 'negative_z'"
            for coord in systems[domain][convention]['coordinates']:
                assert coord in systems[domain][convention], \
                    f"{domain} ({convention}) is missing entry '{coord}'"
                assert systems[domain][convention][coord][0] in \
                    ["unbound", "bound", "cyclic"], \
                    f"{domain} ({convention}), {coord}[0] must be 'unbound', "\
                    "'bound', or 'cyclic'."
예제 #20
0
def test_coordinates_init_val():
    """Test initializing Coordinates with values of different type and size."""

    # test input: scalar
    c1 = 1
    # test input: 2 element vectors
    c2 = [1, 2]  # list
    c3 = np.asarray(c2)  # flat np.array
    c4 = np.atleast_2d(c2)  # row vector np.array
    c5 = np.transpose(c4)  # column vector np.array
    # test input: 3 element vector
    c6 = [1, 2, 3]
    # test input: 2D matrix
    c7 = np.array([[1, 2, 3], [1, 2, 3]])
    # test input: 3D matrix
    c8 = np.array([[[1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3]]])

    # tests that have to path
    # input scalar coordinate
    Coordinates(c1, c1, c1)
    # input list of coordinates
    Coordinates(c2, c2, c2)
    # input scalar and lists
    Coordinates(c1, c2, c2)
    # input flat np.arrays
    Coordinates(c3, c3, c3)
    # input non flat vectors
    Coordinates(c3, c4, c5)
    # input 2D data
    Coordinates(c1, c1, c7)
    # input 3D data
    Coordinates(c1, c1, c8)

    # tests that have to fail
    with raises(AssertionError):
        Coordinates(c2, c2, c6)
    with raises(AssertionError):
        Coordinates(c6, c6, c7)
    with raises(AssertionError):
        Coordinates(c2, c2, c8)
예제 #21
0
def test_orientations_show(views, ups, positions, orientations):
    """
    Visualize orientations via `Orientations.show()`
    with and without `positions`.
    """
    # default orientation
    Orientations().show()
    # single vectors no position
    view = [1, 0, 0]
    up = [0, 1, 0]
    orientation_single = Orientations.from_view_up(view, up)
    orientation_single.show()
    # with position
    position = Coordinates(0, 1, 0)
    orientation_single.show(position)

    # multiple vectors no position
    orientations.show()
    # with matching number of positions
    orientations.show(positions)

    # select what to show
    orientations.show(show_views=False)
    orientations.show(show_ups=False)
    orientations.show(show_rights=False)
    orientations.show(show_views=False, show_ups=False)
    orientations.show(show_views=False, show_rights=False)
    orientations.show(show_ups=False, show_rights=False)
    orientations.show(positions=positions, show_views=False, show_ups=False)

    # with positions provided as Coordinates
    positions = np.asarray(positions)
    positions = Coordinates(positions[:, 0], positions[:, 1], positions[:, 2])
    orientations.show(positions)
    # with non-matching positions
    positions = Coordinates(0, 1, 0)
    with raises(ValueError):
        orientations.show(positions)
예제 #22
0
def test_multiple_getter_with_conversion():
    """Test output of 500 random sequential conversions."""
    # test N successive coordinate conversions
    N = 500

    # get list of available coordinate systems
    coords = Coordinates()
    systems = coords._systems()

    # get reference points in cartesian coordinate system
    points = [
        'positive_x', 'positive_y', 'positive_z', 'negative_x', 'negative_y',
        'negative_z'
    ]
    pts = np.array([systems['cart']['right'][point] for point in points])

    # init the system
    coords.set_cart(pts[:, 0], pts[:, 1], pts[:, 2])

    # list of domains
    domains = list(systems)

    for ii in range(N):
        # randomly select a coordinate system
        domain = domains[np.random.randint(len(domains))]
        conventions = list(systems[domain])
        convention = conventions[np.random.randint(len(conventions))]
        # convert points to selected system
        pts = eval(f"coords.get_{domain}('{convention}', convert=True)")
        # get the reference
        ref = np.array(
            [systems[domain][convention][point] for point in points])
        # check
        npt.assert_allclose(pts, ref, atol=1e-15)
        # print
        print(f"Tolerance met in iteration {ii}")
예제 #23
0
def test_get_nearest_cart():
    """Tests returns of get_nearest_cart."""
    # test only 1D case since most of the code from self.get_nearest_k is used
    x = np.arange(6)
    coords = Coordinates(x, 0, 0)
    i, m = coords.get_nearest_cart(2.5, 0, 0, 1.5)
    npt.assert_allclose(i, np.array([1, 2, 3, 4]))
    npt.assert_allclose(m, np.array([0, 1, 1, 1, 1, 0]))

    # test search with empty results
    i, m = coords.get_nearest_cart(2.5, 0, 0, .1)
    assert len(i) == 0
    npt.assert_allclose(m, np.array([0, 0, 0, 0, 0, 0]))

    # test out of range parameters
    with raises(AssertionError):
        coords.get_nearest_cart(1, 0, 0, -1)
예제 #24
0
def coordinates():
    """ Coordinates object.
    """
    return Coordinates([0, 1], [2, 3], [4, 5])
예제 #25
0
def test___eq___differInConvention_notEqual():
    coordinates = Coordinates(domain='sph', convention='top_elev')
    actual = Coordinates(domain='sph', convention='front')
    assert not coordinates == actual
예제 #26
0
def test_orientations_from_view_up_show_coordinate_system_change(
        views, ups, positions):
    """
    Create `Orientations` from view and up vectors in the spherical domain
    as well as in the carteesian domain, and visualize both to compare them
    manually by eye.
    """
    # Carteesian: Visualize to manually validate orientations
    views = np.asarray(views)
    ups = np.asarray(ups)
    views = Coordinates(views[:, 0], views[:, 1], views[:, 2])
    ups = Coordinates(ups[:, 0], ups[:, 1], ups[:, 2])

    positions = np.asarray(positions)
    positions = Coordinates(positions[:, 0], positions[:, 1], positions[:, 2])
    orient_from_cart = Orientations.from_view_up(views, ups)
    orient_from_cart.show(positions)

    # Convert to spherical: And again visualize to manually validate
    views.get_sph(convert=True)
    ups.get_sph(convert=True)
    positions.get_sph(convert=True)

    orient_from_sph = Orientations.from_view_up(views, ups)
    orient_from_sph.show(positions)

    # Check if coordinate system has not been changed by orientations
    assert views._system['domain'] == 'sph', (
        "Coordinate system has been changed by Orientations.")
    assert ups._system['domain'] == 'sph', (
        "Coordinate system has been changed by Orientations.")
    assert positions._system['domain'] == 'sph', (
        "Coordinate system has been changed by Orientations.show().")
예제 #27
0
파일: io.py 프로젝트: pyfar-seminar/pyfar
def read_sofa(filename):
    """
    Import a SOFA file as :py:class:`~pyfar.classes.audio.Signal` object.

    Parameters
    ----------
    filename : string, Path
        Input SOFA file (cf. [#]_, [#]_).

    Returns
    -------
    signal : Signal
        :py:class:`~pyfar.classes.audio.Signal` object containing the data
        stored in `SOFA_Object.Data.IR`.
        `cshape` is equal to ``(number of measurements, number of receivers)``.
    source_coordinates : Coordinates
        Coordinates object containing the data stored in
        `SOFA_object.SourcePosition`. The domain, convention and unit are
        automatically matched.
    receiver_coordinates : Coordinates
        Coordinates object containing the data stored in
        `SOFA_object.RecevierPosition`. The domain, convention and unit are
        automatically matched.

    Notes
    -----
    * This function is based on the python-sofa [#]_.
    * Currently, only SOFA files of `DataType` ``FIR`` are supported.

    References
    ----------
    .. [#] https://www.sofaconventions.org
    .. [#] “AES69-2015: AES Standard for File Exchange-Spatial Acoustic Data
        File Format.”, 2015.
    .. [#] https://github.com/spatialaudio/python-sofa

    """
    sofafile = sofa.Database.open(filename)
    # Check for DataType
    if sofafile.Data.Type == 'FIR':
        domain = 'time'
        data = np.asarray(sofafile.Data.IR)
        sampling_rate = sofafile.Data.SamplingRate.get_values()
        # Check for units
        if sofafile.Data.SamplingRate.Units != 'hertz':
            raise ValueError(
                "SamplingRate:Units"
                "{sofafile.Data.SamplingRate.Units} is not supported.")
    else:
        raise ValueError("DataType {sofafile.Data.Type} is not supported.")
    signal = Signal(data, sampling_rate, domain=domain)

    # Source
    s_values = sofafile.Source.Position.get_values()
    s_domain, s_convention, s_unit = _sofa_pos(sofafile.Source.Position.Type)
    source_coordinates = Coordinates(
        s_values[:, 0],
        s_values[:, 1],
        s_values[:, 2],
        domain=s_domain,
        convention=s_convention,
        unit=s_unit)
    # Receiver
    r_values = sofafile.Receiver.Position.get_values()
    r_domain, r_convention, r_unit = _sofa_pos(sofafile.Receiver.Position.Type)
    receiver_coordinates = Coordinates(
        r_values[:, 0],
        r_values[:, 1],
        r_values[:, 2],
        domain=r_domain,
        convention=r_convention,
        unit=r_unit)

    return signal, source_coordinates, receiver_coordinates
예제 #28
0
def test___eq___differInShComment_notEqual():
    coordinates = Coordinates(1, 2, 3, comment="Madre mia!")
    actual = Coordinates(1, 2, 3, comment="Oh my woooooosh!")
    assert not coordinates == actual
예제 #29
0
def test___eq___differInShOrder_notEqual():
    coordinates = Coordinates(1, 2, 3, sh_order=2)
    actual = Coordinates(1, 2, 3, sh_order=8)
    assert not coordinates == actual
예제 #30
0
def test___eq___differInWeigths_notEqual():
    coordinates = Coordinates(1, 2, 3, weights=.5)
    actual = Coordinates(1, 2, 3, weights=0.0)
    assert not coordinates == actual