def test_fill(MouseEvent): """Test filling label.""" data = np.ones((20, 20), dtype=np.int32) data[:5, :5] = 2 data[-5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5]) == 2 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.mode = 'fill' layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 0), view_direction=None, dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(19, 19), view_direction=None, dims_displayed=(0, 1), dims_point=(0, 0), ) ) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 5 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1
def test_changing_labels_dims(): """Test changing Labels data including dimensionality.""" shape_a = (10, 15) shape_b = (20, 12, 6) np.random.seed(0) data_a = np.random.randint(20, size=shape_a) data_b = np.random.randint(20, size=shape_b) layer = Labels(data_a) layer.data = data_b assert np.all(layer.data == data_b) assert layer.ndim == len(shape_b) assert layer.shape == shape_b assert layer.dims.range == [(0, m, 1) for m in shape_b] assert layer._data_view.shape == shape_b[-2:]
def test_float_labels(): """Test instantiating labels layer with floats""" shape = (10, 10) np.random.seed(0) data = np.random.uniform(0, 20, size=shape) with pytest.warns(UserWarning): layer = Labels(data) assert np.issubdtype(layer.data.dtype, np.integer) data0 = np.random.uniform(20, size=(20, 20)) data1 = data0[::2, ::2].astype(np.int32) data = [data0, data1] with pytest.warns(UserWarning): layer = Labels(data) assert all(np.issubdtype(d.dtype, np.integer) for d in layer.data)
def test_rendering_init(): shape = (6, 10, 15) np.random.seed(0) data = np.random.randint(20, size=shape) layer = Labels(data, rendering='iso_categorical') assert layer.rendering == LabelsRendering.ISO_CATEGORICAL.value
def test_max_label_tensorstore(labels_data_4d): ts = pytest.importorskip('tensorstore') with TemporaryDirectory(suffix='.zarr') as fout: labels_temp = zarr.open( fout, mode='w', shape=labels_data_4d.shape, dtype=np.uint32, chunks=(1, 1, 8, 9), ) labels_temp[:] = labels_data_4d labels_ts_spec = { 'driver': 'zarr', 'kvstore': { 'driver': 'file', 'path': fout }, 'path': '', 'metadata': { 'dtype': labels_temp.dtype.str, 'order': labels_temp.order, 'shape': labels_data_4d.shape, }, } data = ts.open(labels_ts_spec, create=False, open=True).result() layer = Labels(data) new_label(layer) assert layer.selected_label == 4
def test_layer_action_menu(qapp): """Test the actions in LAYER_ACTIONS.""" menu = QtActionContextMenu(_LAYER_ACTIONS) layer_list = LayerList([]) menu.update_from_context(layer_list._ctx) assert not menu._get_action('napari:convert_to_image').isEnabled() layer_list.append(Labels(np.zeros((8, 8), int))) menu.update_from_context(layer_list._ctx) assert menu._get_action('napari:convert_to_image').isEnabled() assert not menu._get_action('napari:convert_to_labels').isEnabled() layer_list.append(Image(np.zeros((8, 8)))) menu.update_from_context(layer_list._ctx) assert not menu._get_action('napari:convert_to_image').isEnabled() assert menu._get_action('napari:convert_to_labels').isEnabled() assert not menu._get_action('napari:link_selected_layers').isEnabled() layer_list.select_all() menu.update_from_context(layer_list._ctx) assert menu._get_action('napari:link_selected_layers').isEnabled() assert not menu._get_action('napari:unlink_selected_layers').isEnabled() layer_list.link_layers() menu.update_from_context(layer_list._ctx) assert not menu._get_action('napari:link_selected_layers').isEnabled() assert menu._get_action('napari:unlink_selected_layers').isEnabled()
def test_3D_labels(): """Test instantiating Labels layer with random 3D data.""" shape = (6, 10, 15) np.random.seed(0) data = np.random.randint(20, size=shape) layer = Labels(data) assert np.all(layer.data == data) assert layer.ndim == len(shape) np.testing.assert_array_equal(layer.extent.data[1] + 1, shape) assert layer._data_view.shape == shape[-2:] assert layer.editable is True layer._slice_dims(ndisplay=3) assert layer._ndisplay == 3 assert layer.editable is False assert layer.mode == 'pan_zoom'
def test_get_status_with_custom_index(): """See https://github.com/napari/napari/issues/3811""" data = np.zeros((10, 10), dtype=np.uint8) data[2:5, 2:-2] = 1 data[5:-2, 2:-2] = 2 layer = Labels(data) df = pd.DataFrame({ 'text1': [1, 3], 'text2': [7, -2], 'index': [1, 2] }, index=[1, 2]) layer.properties = df assert layer.get_status((0, 0)) == 'Labels [0 0]: 0; [No Properties]' assert layer.get_status((3, 3)) == 'Labels [3 3]: 1; text1: 1, text2: 7' assert layer.get_status((6, 6)) == 'Labels [6 6]: 2; text1: 3, text2: -2'
def test_changing_labels_dims(): """Test changing Labels data including dimensionality.""" shape_a = (10, 15) shape_b = (20, 12, 6) np.random.seed(0) data_a = np.random.randint(20, size=shape_a) data_b = np.random.randint(20, size=shape_b) layer = Labels(data_a) # Prep indices for swtich to 3D layer._indices = (0, ) + layer._indices layer.data = data_b assert np.all(layer.data == data_b) assert layer.ndim == len(shape_b) assert layer.shape == shape_b assert layer.range == tuple((0, m, 1) for m in shape_b) assert layer._data_view.shape == shape_b[-2:]
def test_world_data_extent(): """Test extent after applying transforms.""" np.random.seed(0) shape = (6, 10, 15) data = np.random.randint(20, size=(shape)) layer = Labels(data) extent = np.array(((0,) * 3, np.subtract(shape, 1))) check_layer_world_data_extent(layer, extent, (3, 1, 1), (10, 20, 5))
def test_3d_video_and_3d_scale_translate_then_scale_translate_padded(): # See the GitHub issue for more details: # https://github.com/napari/napari/issues/2967 data = np.zeros((3, 5, 11, 11), dtype=int) labels = Labels(data, scale=(2, 1, 1), translate=(5, 5, 5)) np.testing.assert_array_equal(labels.scale, (1, 2, 1, 1)) np.testing.assert_array_equal(labels.translate, (0, 5, 5, 5))
def test_erase(Event): """Test erasing labels with different brush sizes.""" data = np.ones((20, 20)) layer = Labels(data) layer.brush_size = 10 layer.mode = 'erase' layer.selected_label = 3 layer.position = (0, 0) # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) layer.position = (19, 19) # Simulate drag event = ReadOnlyWrapper(Event(type='mouse_move', is_dragging=True)) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper(Event(type='mouse_release', is_dragging=False)) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but non outside it. assert np.unique(layer.data[:5, :5]) == 0 assert np.unique(layer.data[-5:, -5:]) == 0 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1
def test_get_value_ray_3d_transposed(): """Test using _get_value_ray to interrogate labels in 3D with the dimensions trasposed. """ # make a mock mouse event mouse_event = MouseEvent( pos=[25, 25], position=[10, 5, 5, 1], dims_point=[0, 0, 0, 1], dims_displayed=[1, 3, 2], view_direction=[1, 0, 0, 0], ) data = np.zeros((5, 20, 20, 20), dtype=int) data[1, 0:10, 0:10, 0:10] = 1 labels = Labels(data, scale=(1, 2, 1, 1), translate=(0, 5, 5, 5)) # set the dims to the slice with labels labels._slice_dims((1, 0, 0, 0), ndisplay=3, order=(0, 1, 3, 2)) labels.set_view_slice() value = labels._get_value_ray( start_point=np.array([1, 0, 5, 5]), end_point=np.array([1, 20, 5, 5]), dims_displayed=mouse_event.dims_displayed, ) assert value == 1
def test_fill(Event): """Test filling label.""" data = np.ones((20, 20)) data[:5, :5] = 2 data[-5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5]) == 2 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.mode = 'fill' layer.position = (0, 0) layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 layer.position = (19, 19) layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper(Event(type='mouse_press', is_dragging=False)) mouse_press_callbacks(layer, event) assert np.unique(layer.data[:5, :5]) == 4 assert np.unique(layer.data[-5:, -5:]) == 5 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1
def test_all_zeros_labels(): """Test instantiating Labels layer with all zeros data.""" shape = (10, 15) data = np.zeros(shape, dtype=int) layer = Labels(data) assert np.all(layer.data == data) assert layer.ndim == len(shape) assert layer.shape == shape assert layer._data_view.shape == shape[-2:]
def test_3D_labels(): """Test instantiating Labels layer with random 3D data.""" shape = (6, 10, 15) np.random.seed(0) data = np.random.randint(20, size=shape) layer = Labels(data) assert np.all(layer.data == data) assert layer.ndim == len(shape) assert layer.shape == shape assert layer._data_view.shape == shape[-2:]
def test_mouse_move(): """Test painting labels with different brush sizes.""" np.random.seed(0) data = np.random.randint(20, size=(20, 20)) layer = Labels(data) layer.brush_size = 10 layer.mode = 'paint' layer.selected_label = 3 layer._last_cursor_coord = (0, 0) layer.coordinates = (19, 19) Event = collections.namedtuple('Event', 'is_dragging') event = Event(is_dragging=True) layer.on_mouse_move(event) assert np.unique(layer.data[:5, :5]) == 3 assert np.unique(layer.data[-5:, -5:]) == 3
def test_random_labels(): """Test instantiating Labels layer with random 2D data.""" shape = (10, 15) np.random.seed(0) data = np.random.randint(20, size=shape) layer = Labels(data) assert np.all(layer.data == data) assert layer.ndim == len(shape) assert layer.shape == shape assert layer.range == tuple((0, m, 1) for m in shape) assert layer._data_view.shape == shape[-2:]
def test_random_labels(): """Test instantiating Labels layer with random 2D data.""" shape = (10, 15) np.random.seed(0) data = np.random.randint(20, size=shape) layer = Labels(data) assert np.all(layer.data == data) assert layer.ndim == len(shape) np.testing.assert_array_equal(layer.extent.data[1] + 1, shape) assert layer._data_view.shape == shape[-2:] assert layer.editable is True
def test_fill_nD_plane(Event): """Test filling label nD plane.""" data = np.ones((20, 20, 20), dtype=np.int32) data[:5, :5, :5] = 2 data[0, 8:10, 8:10] = 2 data[-5:, -5:, -5:] = 3 layer = Labels(data) assert np.unique(layer.data[:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.mode = 'fill' layer.selected_label = 4 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 0, 0))) mouse_press_callbacks(layer, event) assert np.unique(layer.data[0, :5, :5]) == 4 assert np.unique(layer.data[1:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, 8:10, 8:10]) == 2 layer.selected_label = 5 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 19, 19))) mouse_press_callbacks(layer, event) assert np.unique(layer.data[0, :5, :5]) == 4 assert np.unique(layer.data[1:5, :5, :5]) == 2 assert np.unique(layer.data[-5:, -5:, -5:]) == 3 assert np.unique(layer.data[1:5, -5:, -5:]) == 1 assert np.unique(layer.data[-5:, :5, -5:]) == 1 assert np.unique(layer.data[0, -5:, -5:]) == 5 assert np.unique(layer.data[0, :5, -5:]) == 5 assert np.unique(layer.data[0, 8:10, 8:10]) == 2
def test_midpoint_3d_nonempty_ray(make_napari_viewer): viewer = make_napari_viewer() viewer.dims.ndisplay = 3 mock_data = np.zeros(shape=(5, 5, 5), dtype="uint8") mock_data[1:4, 1:4, 1:4] = 1 layer_data = Labels(mock_data) viewer.add_layer(layer_data) mouse_event = MockMouseEvent((2, 2, 0), [0, 1, 1]) result = find_midpoint_of_first_segment(layer_data, mouse_event) np.testing.assert_allclose(result, [2., 3.5, 1.5])
def test_midpoint_3d_empty_ray(make_napari_viewer): viewer = make_napari_viewer() viewer.dims.ndisplay = 3 mock_data = np.zeros(shape=(5, 5, 5), dtype="uint8") layer_data = Labels(mock_data) mouse_event = MockMouseEvent((2, 2, 0), [1, 0, 0]) viewer.add_layer(layer_data) result = find_midpoint_of_first_segment(layer_data, mouse_event) assert result is None mock_data[1:4, 1:4, 1:4] = 1 layer_data = Labels(mock_data) mouse_event = MockMouseEvent((2, 2, 0), [1, 0, 0]) viewer.add_layer(layer_data) result = find_midpoint_of_first_segment(layer_data, mouse_event) assert result is None
def layer_data_and_types(): np.random.seed(0) layers = [ Image(np.random.rand(20, 20)), Labels(np.random.randint(10, size=(20, 2))), Points(np.random.rand(20, 2)), Shapes(np.random.rand(10, 2, 2)), Vectors(np.random.rand(10, 2, 2)), ] layer_data = [l.as_layer_data_tuple() for l in layers] layer_types = [ld[2] for ld in layer_data] return layer_data, layer_types
def test_pick(Event): """Test picking label.""" data = np.ones((20, 20), dtype=np.int32) data[:5, :5] = 2 data[-5:, -5:] = 3 layer = Labels(data) assert layer.selected_label == 1 layer.mode = 'pick' # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 0))) mouse_press_callbacks(layer, event) assert layer.selected_label == 2 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(19, 19))) mouse_press_callbacks(layer, event) assert layer.selected_label == 3
def test_paint_3d(MouseEvent): """Test filling label nD.""" data = np.zeros((21, 21, 21), dtype=np.int32) data[10, 10, 10] = 1 layer = Labels(data) layer._slice_dims(point=(0, 0, 0), ndisplay=3) layer.n_edit_dimensions = 3 layer.mode = 'paint' layer.selected_label = 4 layer.brush_size = 3 # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0.1, 0, 0), view_direction=np.full(3, np.sqrt(3)), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) np.testing.assert_array_equal(np.unique(layer.data), [0, 4]) num_filled = np.bincount(layer.data.ravel())[4] assert num_filled > 1 layer.mode = 'erase' # Simulate click event = ReadOnlyWrapper( MouseEvent( type='mouse_press', is_dragging=False, position=(0, 10, 10), view_direction=(1, 0, 0), dims_displayed=(0, 1, 2), dims_point=(0, 0, 0), ) ) mouse_press_callbacks(layer, event) new_num_filled = np.bincount(layer.data.ravel())[4] assert new_num_filled < num_filled
def test_paint_scale(Event, brush_shape, expected_sum): """Test painting labels with circle/square brush when scaled.""" data = np.ones((20, 20), dtype=np.int32) layer = Labels(data, scale=(2, 2)) layer.brush_size = 10 layer.brush_shape = brush_shape layer.mode = 'paint' layer.selected_label = 3 # Simulate click event = ReadOnlyWrapper( Event(type='mouse_press', is_dragging=False, position=(0, 0))) mouse_press_callbacks(layer, event) # Simulate drag event = ReadOnlyWrapper( Event(type='mouse_move', is_dragging=True, position=(39, 39))) mouse_move_callbacks(layer, event) # Simulate release event = ReadOnlyWrapper( Event(type='mouse_release', is_dragging=False, position=(39, 39))) mouse_release_callbacks(layer, event) # Painting goes from (0, 0) to (19, 19) with a brush size of 10, changing # all pixels along that path, but none outside it. assert np.unique(layer.data[:8, :8]) == 3 assert np.unique(layer.data[-8:, -8:]) == 3 assert np.unique(layer.data[:5, -5:]) == 1 assert np.unique(layer.data[-5:, :5]) == 1 assert np.sum(layer.data == 3) == expected_sum
def test_is_default_color(): """Test labels layer default color for None and background Previously, setting color to just default values would change color mode to DIRECT and display a black layer. This test ensures `is_default_color` is correctly checking against layer defaults, and `color_mode` is only changed when appropriate. See - https://github.com/napari/napari/issues/2479 - https://github.com/napari/napari/issues/2953 """ data = np.random.randint(20, size=(10, 15)) layer = Labels(data) # layer gets instantiated with defaults current_color = layer.color assert layer._is_default_colors(current_color) # setting color to default colors doesn't update color mode layer.color = current_color assert layer.color_mode == 'auto' # new colors are not default new_color = {0: 'white', 1: 'red', 3: 'green'} assert not layer._is_default_colors(new_color) # setting the color with non-default colors updates color mode layer.color = new_color assert layer.color_mode == 'direct'
def test_paint_2d_xarray(brush_shape, expected_sum): """Test the memory usage of painting an xarray indirectly via timeout.""" data = xr.DataArray(np.zeros((3, 3, 1024, 1024))) layer = Labels(data) layer.brush_size = 12 layer.brush_shape = brush_shape layer.mode = 'paint' layer.paint((1, 1, 512, 512), 3) assert isinstance(layer.data, xr.DataArray) assert layer.data.sum() == expected_sum
def test_changing_labels(): """Test changing Labels data.""" shape_a = (10, 15) shape_b = (20, 12) shape_c = (10, 10) np.random.seed(0) data_a = np.random.randint(20, size=shape_a) data_b = np.random.randint(20, size=shape_b) layer = Labels(data_a) layer.data = data_b assert np.all(layer.data == data_b) assert layer.ndim == len(shape_b) np.testing.assert_array_equal(layer.extent.data[1] + 1, shape_b) assert layer._data_view.shape == shape_b[-2:] data_c = np.zeros(shape_c, dtype=bool) layer.data = data_c assert np.issubdtype(layer.data.dtype, np.integer) data_c = data_c.astype(np.float32) with pytest.raises(TypeError): layer.data = data_c
def test_random_pyramid(): """Test instantiating Labels layer with random 2D pyramid data.""" shapes = [(40, 20), (20, 10), (10, 5)] np.random.seed(0) data = [np.random.randint(20, size=s) for s in shapes] layer = Labels(data, is_pyramid=True) assert layer.data == data assert layer.is_pyramid is True assert layer.editable is False assert layer.ndim == len(shapes[0]) assert layer.shape == shapes[0] assert layer.rgb is False assert layer._data_view.ndim == 2