diff --git a/src/pynwb/ophys.py b/src/pynwb/ophys.py index 2240c8a05..1eeaad766 100644 --- a/src/pynwb/ophys.py +++ b/src/pynwb/ophys.py @@ -277,6 +277,35 @@ def add_roi(self, **kwargs): rkwargs['voxel_mask'] = voxel_mask return super(PlaneSegmentation, self).add_row(**rkwargs) + @staticmethod + def pixel_to_image(pixel_mask): + """ + Converts a 2D pixel_mask of a ROI into an image_mask. + """ + image_matrix = np.zeros(np.shape(pixel_mask)) + npmask = np.asarray(pixel_mask) + x_coords = npmask[:, 0].astype(np.int) + y_coords = npmask[:, 1].astype(np.int) + weights = npmask[:, -1] + image_matrix[y_coords, x_coords] = weights + return image_matrix + + @staticmethod + def image_to_pixel(image_mask): + """ + Converts an image_mask of a ROI into a pixel_mask + """ + pixel_mask = [] + it = np.nditer(image_mask, flags=['multi_index']) + while not it.finished: + weight = it[0][()] + if weight > 0: + x = it.multi_index[0] + y = it.multi_index[1] + pixel_mask.append([x, y, weight]) + it.iternext() + return pixel_mask + @docval({'name': 'description', 'type': str, 'doc': 'a brief description of what the region is'}, {'name': 'region', 'type': (slice, list, tuple), 'doc': 'the indices of the table', 'default': slice(None)}, {'name': 'name', 'type': str, 'doc': 'the name of the ROITableRegion', 'default': 'rois'}) diff --git a/tests/unit/test_ophys.py b/tests/unit/test_ophys.py index bd7632d80..4d1f6372b 100644 --- a/tests/unit/test_ophys.py +++ b/tests/unit/test_ophys.py @@ -157,6 +157,11 @@ def getBoilerPlateObjects(self): 300., 'indicator', 'location', (1, 2, 1, 2, 3), 4.0, 'unit', 'reference_frame') return iSS, ip + def create_basic_plane_segmentation(self): + """Creates a basic plane segmentation used for testing""" + iSS, ip = self.getBoilerPlateObjects() + return PlaneSegmentation('description', ip, 'test_name', iSS) + def test_init(self): w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]] @@ -220,15 +225,33 @@ def test_init_voxel_mask(self): def test_init_3d_image_mask(self): img_masks = np.random.randn(2, 20, 30, 4) - iSS, ip = self.getBoilerPlateObjects() - - pS = PlaneSegmentation('description', ip, 'test_name', iSS) + pS = self.create_basic_plane_segmentation() pS.add_roi(image_mask=img_masks[0]) pS.add_roi(image_mask=img_masks[1]) self.assertTrue(np.allclose(pS['image_mask'][0], img_masks[0])) self.assertTrue(np.allclose(pS['image_mask'][1], img_masks[1])) + def test_conversion_of_2d_pixel_mask_to_image_mask(self): + pixel_mask = [[0, 0, 1.0], [1, 0, 2.0], [2, 0, 2.0]] + + pS = self.create_basic_plane_segmentation() + + img_mask = pS.pixel_to_image(pixel_mask) + np.testing.assert_allclose(img_mask, np.asarray([[1, 2, 2.0], + [0, 0, 0.0], + [0, 0, 0.0]])) + + def test_conversion_of_2d_image_mask_to_pixel_mask(self): + image_mask = np.asarray([[1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0]]) + + pS = self.create_basic_plane_segmentation() + + pixel_mask = pS.image_to_pixel(image_mask) + np.testing.assert_allclose(pixel_mask, np.asarray([[0, 0, 1.0], [1, 1, 1.0], [2, 2, 1.0]])) + def test_init_image_mask(self): w, h = 5, 5 img_mask = [[[1.0 for x in range(w)] for y in range(h)], [[2.0 for x in range(w)] for y in range(h)]]