def test_roi_on_motion_border():
    """
    Test that ROIs which overlap the motion border of a movie result in traces
    that are full of NaNs
    """

    movie_data = np.zeros((23, 100, 130))
    movie_data[:, 0:40, 0:40] = 3.0
    movie_data[:, 0:40, 90:] = 4.0
    movie_data[:, 60:, 0:40] = 5.0
    movie_data[:, 40:, 90:] = 6.0

    motion_border = {'x0': 2.0, 'x1': 3.0, 'y0': 4.0, 'y1': 5.0}

    motion_border_list = [
        motion_border['x0'], motion_border['x1'], motion_border['y0'],
        motion_border['y1']
    ]

    mask_list = []

    pix_list = np.array([[120, 10], [120, 11], [121, 10], [121, 11]])
    movie_data[:, pix_list[:, 1], pix_list[:, 0]] = 14.0

    mask = roi_masks.create_roi_mask(130,
                                     100,
                                     motion_border_list,
                                     pix_list=pix_list,
                                     label='roi_0')
    mask_list.append(mask)

    pix_list = np.array([[126, 10], [126, 11], [127, 10], [127, 11]])
    mask = roi_masks.create_roi_mask(130,
                                     100,
                                     motion_border_list,
                                     pix_list=pix_list,
                                     label='roi_1')
    mask_list.append(mask)

    (roi_trace, neuropil_trace,
     exc) = roi_masks.calculate_roi_and_neuropil_traces(
         movie_data, mask_list, motion_border_list)

    np.testing.assert_array_equal(roi_trace[0, :],
                                  14.0 * np.ones(23, dtype=float))
    np.testing.assert_array_equal(neuropil_trace[0, :],
                                  4.0 * np.ones(23, dtype=float))
    np.testing.assert_array_equal(roi_trace[1, :],
                                  np.NaN * np.ones(23, dtype=float))
def test_create_neuropil_mask():

    image_width = 100
    image_height = 80

    # border = [image_width-1, 0, image_height-1, 0]
    border = [5, 5, 5, 5]

    roi_mask = np.zeros((image_height, image_width), dtype=np.uint8)
    roi_mask[40:45, 30:35] = 1

    combined_binary_mask = np.zeros((image_height, image_width),
                                    dtype=np.uint8)
    combined_binary_mask[:, 45:] = 1

    roi = roi_masks.create_roi_mask(image_w=image_width,
                                    image_h=image_height,
                                    border=border,
                                    roi_mask=roi_mask)

    obtained = roi_masks.create_neuropil_mask(roi, border,
                                              combined_binary_mask)

    expected_mask = np.zeros((58 - 27, 45 - 17), dtype=np.uint8)
    expected_mask[:, :] = 1

    assert np.allclose(expected_mask, obtained.mask)
    assert obtained.x == 17
    assert obtained.y == 27
    assert obtained.width == 28
    assert obtained.height == 31
    def get_trace(self, roi_list: List[OphysROI]) -> dc_types.ROISetDict:
        """
        Extract the traces from a movie as defined by the ROIs in roi_list

        Parameters
        ----------
        roi_list -- a list of OphysROI instantiations
                    specifying the ROIs from which to
                    extract traces

        Returns
        -------
        output -- a decrosstalk_types.ROISetDict containing the ROI and
                  neuropil traces associated with roi_list. For each ROI
                  in the ROISetDict, only the 'signal' channel will be
                  populated, this with the trace extracted from the movie.
        """
        motion_border = [
            self._motion_border['x0'], self._motion_border['x1'],
            self._motion_border['y0'], self._motion_border['y1']
        ]

        height = self.data.shape[1]
        width = self.data.shape[2]

        roi_mask_list = []
        for roi in roi_list:
            pixels = np.argwhere(roi.mask_matrix)
            pixels[:, 0] += roi.y0
            pixels[:, 1] += roi.x0
            mask = roi_masks.create_roi_mask(width,
                                             height,
                                             motion_border,
                                             pix_list=pixels[:, [1, 0]],
                                             label=str(roi.roi_id),
                                             mask_group=-1)

            roi_mask_list.append(mask)

        _traces = roi_masks.calculate_roi_and_neuropil_traces(
            self.data, roi_mask_list, motion_border)
        roi_traces = _traces[0]
        neuropil_traces = _traces[1]

        output = dc_types.ROISetDict()
        for i_roi, roi in enumerate(roi_list):

            trace = dc_types.ROIChannels()
            trace['signal'] = roi_traces[i_roi]
            output['roi'][roi.roi_id] = trace

            trace = dc_types.ROIChannels()
            trace['signal'] = neuropil_traces[i_roi]
            output['neuropil'][roi.roi_id] = trace

        return output
def test_init_by_pixels_large():
    a = np.random.random((512, 512))
    a[a > 0.5] = 1

    m = roi_masks.create_roi_mask(512,
                                  512, [0, 0, 0, 0],
                                  pix_list=np.argwhere(a))

    npx = len(np.where(a)[0])
    assert npx == len(np.where(m.get_mask_plane())[0])
def test_init_by_pixels_with_border():
    a = np.array([[1, 1], [2, 1]])

    m = roi_masks.create_roi_mask(3, 3, [1, 1, 1, 1], pix_list=a)

    assert m.x == 1
    assert m.width == 2
    assert m.y == 1
    assert m.height == 1
    assert m.overlaps_motion_border is True
def test_init_by_pixels():
    a = np.array([[0, 0], [1, 1], [1, 0]])

    m = roi_masks.create_roi_mask(2, 2, [0, 0, 0, 0], pix_list=a)

    mp = m.get_mask_plane()

    assert mp[0, 0] == 1
    assert mp[1, 1] == 1
    assert mp[1, 0] == 0
    assert mp[1, 1] == 1

    assert m.x == 0
    assert m.width == 2
    assert m.y == 0
    assert m.height == 2
def roi_mask_list(image_dims, motion_border):

    base_pixels = np.argwhere(np.ones((10, 10)))

    masks = []
    for ii in range(10):
        pixels = base_pixels + ii * 10
        masks.append(
            roi_masks.create_roi_mask(image_dims['width'],
                                      image_dims['height'],
                                      motion_border,
                                      pix_list=pixels,
                                      label=str(ii),
                                      mask_group=-1))

    return masks
def test_create_empty_neuropil_mask():
    image_width = 100
    image_height = 80

    # border = [image_width-1, 0, image_height-1, 0]
    border = [5, 5, 5, 5]

    roi_mask = np.zeros((image_height, image_width), dtype=np.uint8)
    roi_mask[40:45, 30:35] = 1

    combined_binary_mask = np.zeros((image_height, image_width),
                                    dtype=np.uint8)
    combined_binary_mask[:, :] = 1

    roi = roi_masks.create_roi_mask(image_w=image_width,
                                    image_h=image_height,
                                    border=border,
                                    roi_mask=roi_mask)

    obtained = roi_masks.create_neuropil_mask(roi, border,
                                              combined_binary_mask)

    assert obtained.mask is None
    assert 'zero_pixels' in obtained.flags