def kymogroups_2lines(): _, _, photon_count, parameters = read_dataset_gaussian( "kymo_data_2lines.npz") pixel_size = parameters[0].pixel_size centers = [p.center / pixel_size for p in parameters] image = CalibratedKymographChannel.from_array(photon_count, pixel_size=pixel_size) _, n_frames = image.data.shape lines = KymoLineGroup([ KymoLine(np.arange(0.0, n_frames), np.full(n_frames, c), image) for c in centers ]) # introduce gaps into tracked lines use_frames = np.array([0, 1, -2, -1]) gapped_lines = KymoLineGroup([ KymoLine(line.time_idx[use_frames], line.coordinate_idx[use_frames], image) for line in lines ]) # crop the ends of initial lines and make new set of lines with one cropped and the second full truncated_lines = KymoLineGroup([ KymoLine(np.arange(1.0, n_frames - 2), np.full(n_frames - 3, c), image) for c in centers ]) mixed_lines = KymoLineGroup([truncated_lines[0], lines[1]]) return lines, gapped_lines, mixed_lines
def test_stitching(): channel = CalibratedKymographChannel("test_data", np.array([[]]), 1e9, 1) segment_1 = KymoLine([0, 1], [0, 1], channel) segment_2 = KymoLine([2, 3], [2, 3], channel) segment_3 = KymoLine([2, 3], [0, 0], channel) segment_1b = KymoLine([0, 1], [0, 0], channel) segment_1c = KymoLine([-1, 0, 1], [0, 0, 1], channel) radius = 0.05 segment_1d = KymoLine([0.0, 1.0], [radius + 0.01, radius + 0.01], channel) # Out of stitch range (maximum extension = 1) assert len( stitch_kymo_lines([segment_1, segment_3, segment_2], radius, 1, 2)) == 3 # Out of stitch radius assert len( stitch_kymo_lines([segment_1d, segment_3, segment_2], radius, 2, 2)) == 3 stitched = stitch_kymo_lines([segment_1, segment_3, segment_2], radius, 2, 2) assert len(stitched) == 2 np.testing.assert_allclose(stitched[0].coordinate_idx, [0, 1, 2, 3]) np.testing.assert_allclose(stitched[1].coordinate_idx, [0, 0]) stitched = stitch_kymo_lines([segment_1b, segment_3, segment_2], radius, 2, 2) np.testing.assert_allclose(stitched[0].coordinate_idx, [0, 0, 0, 0]) np.testing.assert_allclose(stitched[0].time_idx, [0, 1, 2, 3]) np.testing.assert_allclose(stitched[1].coordinate_idx, [2, 3]) # Check whether only the last two points are used (meaning we extrapolate [0, 0], [1, 1]) stitched = stitch_kymo_lines([segment_1c, segment_3, segment_2], radius, 2, 2) np.testing.assert_allclose(stitched[0].coordinate_idx, [0, 0, 1, 2, 3]) np.testing.assert_allclose(stitched[0].time_idx, [-1, 0, 1, 2, 3]) # When using all three points, we shouldn't stitch assert len( stitch_kymo_lines([segment_1c, segment_3, segment_2], radius, 2, 3)) == 3 # Check whether the alignment has to work in both directions # - and - should connect l1, l2 = KymoLine([0, 1], [0, 0], channel), KymoLine([2, 2.01], [0, 0], channel) assert len(stitch_kymo_lines([l1, l2], radius, 1, 2)) == 1 # - and | should not connect. l1, l2 = KymoLine([0, 1], [0, 0], channel), KymoLine([2, 2.01], [0, 1], channel) assert len(stitch_kymo_lines([l1, l2], radius, 1, 2)) == 2
def test_kymoline_interpolation(): time_idx = np.array([1.0, 3.0, 5.0]) coordinate_idx = np.array([1.0, 3.0, 3.0]) kymoline = KymoLine(time_idx, coordinate_idx, []) interpolated = kymoline.interpolate() np.testing.assert_allclose(interpolated.time_idx, [1.0, 2.0, 3.0, 4.0, 5.0]) np.testing.assert_allclose(interpolated.coordinate_idx, [1.0, 2.0, 3.0, 3.0, 3.0]) # Test whether concatenation still works after interpolation np.testing.assert_allclose((interpolated + kymoline).time_idx, [1.0, 2.0, 3.0, 4.0, 5.0, 1.0, 3.0, 5.0]) np.testing.assert_allclose((interpolated + kymoline).coordinate_idx, [1.0, 2.0, 3.0, 3.0, 3.0, 1.0, 3.0, 3.0])
def test_refinement_2d(): time_idx = np.array([1, 2, 3, 4, 5]) coordinate_idx = np.array([1, 2, 3, 3, 3]) # Draw image with a deliberate offset offset = 2 data = np.zeros((7, 7)) data[coordinate_idx + offset, time_idx] = 5 data[coordinate_idx - 1 + offset, time_idx] = 1 data[coordinate_idx + 1 + offset, time_idx] = 1 image = CalibratedKymographChannel.from_array(data) line = KymoLine(time_idx[::2], coordinate_idx[::2], image=image) refined_line = refine_lines_centroid([line], 5)[0] np.testing.assert_allclose(refined_line.time_idx, time_idx) np.testing.assert_allclose(refined_line.coordinate_idx, coordinate_idx + offset) # Test whether concatenation still works after refinement np.testing.assert_allclose((refined_line + line).time_idx, np.hstack((time_idx, time_idx[::2]))) np.testing.assert_allclose( (refined_line + line).coordinate_idx, np.hstack((coordinate_idx + offset, coordinate_idx[::2])), )
def test_filter_lines(): channel = CalibratedKymographChannel("test_data", np.array([[]]), 1e9, 1) k1 = KymoLine([1, 2, 3], [1, 2, 3], channel) k2 = KymoLine([2, 3], [1, 2], channel) k3 = KymoLine([2, 3, 4, 5], [1, 2, 4, 5], channel) lines = KymoLineGroup([k1, k2, k3]) assert len(filter_lines(lines, 5)) == 0 assert all([ line1 == line2 for line1, line2 in zip(filter_lines(lines, 5), [k1, k3]) ]) assert all([ line1 == line2 for line1, line2 in zip(filter_lines(lines, 2), [k1, k2, k3]) ])
def test_refinement_line(loc, inv_sigma=0.3): xx = np.arange(0, 50) - loc image = np.exp(-inv_sigma * xx * xx) calibrated_image = CalibratedKymographChannel.from_array( np.expand_dims(image, 1)) line = refine_lines_centroid([KymoLine([0], [25], image=calibrated_image)], 5)[0] np.testing.assert_allclose(line.coordinate_idx, loc, rtol=1e-2)
def test_stitch(kymograph, mockevent): kymo_widget = KymoWidgetGreedy(kymograph, "red", 1, use_widgets=False) k1 = KymoLine( np.array([1, 2, 3]), np.array([1, 1, 1]), CalibratedKymographChannel.from_kymo(kymograph, "red"), ) k2 = KymoLine( np.array([6, 7, 8]), np.array([3, 3, 3]), CalibratedKymographChannel.from_kymo(kymograph, "red"), ) kymo_widget.lines = KymoLineGroup([k1, k2]) # Go into line connection mode kymo_widget._select_state({"new": "Connect Lines"}) assert len(kymo_widget.lines) == 2 in_um, in_s = calibrate_to_kymo(kymograph) # Drag but stop too early (not leading to a connected line) kymo_widget._line_connector.button_down( mockevent(kymo_widget._axes, in_s(3), in_um(1), 3, 0)) kymo_widget._line_connector.button_release( mockevent(kymo_widget._axes, in_s(4), in_um(3), 3, 0)) assert len(kymo_widget.lines) == 2 # Drag all the way (stitch the two) kymo_widget._line_connector.button_down( mockevent(kymo_widget._axes, in_s(3), in_um(1), 3, 0)) kymo_widget._line_connector.button_release( mockevent(kymo_widget._axes, in_s(6), in_um(3), 3, 0)) # Verify the stitched line np.testing.assert_allclose(kymo_widget.lines[0].time_idx, [1, 2, 3, 6, 7, 8]) np.testing.assert_allclose(kymo_widget.lines[0].coordinate_idx, [1, 1, 1, 3, 3, 3]) assert len(kymo_widget.lines) == 1
def test_kymoline_regression_sample_from_image_clamp(): """This tests for a regression that occurred in sample_from_image. When sampling the image, we sample pixels in a region around the line. This sampling procedure is constrained to stay within the image. Previously, we used the incorrect axis to clamp the coordinate. """ # Sampling the bottom row of a three pixel tall image will return [0, 0] instead of [1, 3]; # since both coordinates would be clamped to the edge of the image (sampling nothing).""" img = CalibratedKymographChannel("test_data", np.array([[1, 1, 1], [3, 3, 3]]).T, 1e9, 1) assert np.array_equal( KymoLine([0, 1], [2, 2], img).sample_from_image(0), [1, 3])
def test_stitch_anywhere(start, stop, same_line, kymograph, mockevent): kymo_widget = KymoWidgetGreedy(kymograph, "red", 1, use_widgets=False) k1 = KymoLine( np.array([1, 2, 3, 4, 5]), np.array([1, 1, 1, 3, 3]), CalibratedKymographChannel.from_kymo(kymograph, "red"), ) k2 = KymoLine( np.array([6, 7, 8]), np.array([3, 3, 3]), CalibratedKymographChannel.from_kymo(kymograph, "red"), ) kymo_widget.lines = KymoLineGroup([k1, k2]) # Go into line connection mode kymo_widget._select_state({"new": "Connect Lines"}) in_um, in_s = calibrate_to_kymo(kymograph) # Merge points kymo_widget._line_connector.button_down( mockevent(kymo_widget._axes, in_s(start), in_um(1), 3, 0)) kymo_widget._line_connector.button_release( mockevent(kymo_widget._axes, in_s(stop), in_um(3), 3, 0)) # Verify the stitched line if not same_line: time_result = np.hstack((np.arange(start) + 1, np.arange(stop, 9))) coord_result = np.hstack((np.full(start, 1), np.full(9 - stop, 3))) else: time_result = np.hstack((np.arange(start) + 1, np.arange(stop, 6))) coord_result = np.hstack((np.full(start, 1), np.full(6 - stop, 3))) np.testing.assert_allclose(kymo_widget.lines[0].time_idx, time_result) np.testing.assert_allclose(kymo_widget.lines[0].coordinate_idx, coord_result) assert len(kymo_widget.lines) == 2 if same_line else 1
def kymogroups_close_lines(): _, _, photon_count, parameters = read_dataset_gaussian( "two_gaussians_1d.npz") pixel_size = parameters[0].pixel_size centers = [p.center / pixel_size for p in parameters] image = CalibratedKymographChannel.from_array(photon_count, pixel_size=pixel_size) _, n_frames = image.data.shape lines = KymoLineGroup([ KymoLine(np.arange(0.0, n_frames), np.full(n_frames, c), image) for c in centers ]) return lines
def test_sampling(): test_data = np.array([ [0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0], ]) test_img = CalibratedKymographChannel("test", test_data, 10e9, 5) # Tests the bound handling kymoline = KymoLine([0, 1, 2, 3, 4], [0, 1, 2, 3, 4], test_img) np.testing.assert_allclose(kymoline.sample_from_image(50), [0, 2, 3, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(2), [0, 2, 3, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(1), [0, 2, 2, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(0), [0, 1, 1, 1, 0]) np.testing.assert_allclose( KymoLine([0, 1, 2, 3, 4], [4, 4, 4, 4, 4], test_img).sample_from_image(0), [0, 0, 1, 1, 0]) kymoline = KymoLine([0.1, 1.1, 2.1, 3.1, 4.1], [0.1, 1.1, 2.1, 3.1, 4.1], test_img) np.testing.assert_allclose(kymoline.sample_from_image(50), [0, 2, 3, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(2), [0, 2, 3, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(1), [0, 2, 2, 2, 0]) np.testing.assert_allclose(kymoline.sample_from_image(0), [0, 1, 1, 1, 0]) kymoline = KymoLine([0.1, 1.1, 2.1, 3.1, 4.1], [4.1, 4.1, 4.1, 4.1, 4.1], test_img) np.testing.assert_allclose(kymoline.sample_from_image(0), [0, 0, 1, 1, 0])