Skip to content

Commit

Permalink
Pixel-wise decoding for Polaris (#73)
Browse files Browse the repository at this point in the history
* Pixel-wise decoding and tests
  • Loading branch information
elaubsch authored Aug 24, 2023
1 parent d34f0c0 commit c3a01d8
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 33 deletions.
40 changes: 34 additions & 6 deletions deepcell_spots/applications/polaris.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,7 @@ def _predict(self,
shape `[batch, x, y, channel]`. Channel dimension should less than or equal to
the number of imaging channels. Defaults to None.
image_mpp (float): Microns per pixel for `spots_image`.
threshold (float): Probability threshold for a pixel to be
considered as a spot.
threshold (float): Probability threshold for a pixel to be decoded.
clip (bool): Determines if pixel values will be clipped by percentile.
Defaults to `True`.
mask_threshold (float): Percentile of pixel values in background image used to
Expand Down Expand Up @@ -400,8 +399,7 @@ def _predict(self,

clipped_output_image = np.clip(output_image, 0, 1)
max_proj_images = np.max(clipped_output_image, axis=-1)
spots_locations = max_cp_array_to_point_list_max(max_proj_images,
threshold=threshold, min_distance=1)
spots_locations = [np.argwhere(max_proj_images[i]>threshold) for i in range(max_proj_images.shape[0])]

if self.image_type == 'multiplex':
if self.distribution == 'Gaussian':
Expand Down Expand Up @@ -457,14 +455,44 @@ def _predict(self,
spots_cell_assignments_vec,
decoding_result)
df_intensities = pd.DataFrame(spots_intensities_vec)
return df_spots, df_intensities, segmentation_result
df_results = pd.concat([df_spots, df_intensities], axis=1)

if self.image_type == 'multiplex':
dec_prob_im = np.zeros((spots_image.shape[:3]))

for i in range(len(df_results)):
gene = df_results.loc[i, 'predicted_name']
if gene in ['Background', 'Unknown']:
continue
if 'Blank' in gene:
continue

x = df_results.loc[i, 'x']
y = df_results.loc[i, 'y']
b = df_results.loc[i, 'batch_id']
prob = max_proj_images[b, x, y]

dec_prob_im[b, x, y] = prob

decoded_spots_locations = max_cp_array_to_point_list_max(dec_prob_im,
threshold=None, min_distance=1)
mask = []
for i in range(np.shape(decoded_spots_locations)[1]):
x = decoded_spots_locations[0][i, 0]
y = decoded_spots_locations[0][i, 1]

mask.append(df_results.loc[(df_results.x==x) & (df_results.y==y)].index[0])

df_results = df_results.loc[mask]

return df_results, segmentation_result

def predict(self,
spots_image,
segmentation_image=None,
background_image=None,
image_mpp=None,
threshold=0.95,
threshold=0.01,
clip=True,
mask_threshold=0.5,
maxpool_extra_pixel_num=0,
Expand Down
43 changes: 16 additions & 27 deletions deepcell_spots/applications/polaris_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,10 @@ def test_polaris_app(self):
pred = app.predict(spots_image=spots_image,
segmentation_image=segmentation_image,
background_image=background_image)
df_spots = pred[0]
df_intensities = pred[1]
segmentation_result = pred[2]
df_results = pred[0]
segmentation_result = pred[1]

self.assertEqual(np.sum(df_intensities.values[:,-1]), 0)
self.assertAllGreater(np.sum(df_intensities.values[:,:-1], axis=0), 0)
self.assertEqual(np.sum(df_results.values[:,-1]), 0)

# test prediction type -- singleplex
app = Polaris()
Expand All @@ -221,17 +219,14 @@ def test_polaris_app(self):
pred = app.predict(spots_image=spots_image,
segmentation_image=segmentation_image,
background_image=background_image)
df_spots = pred[0]
df_intensities = pred[1]
segmentation_result = pred[2]
self.assertIsInstance(df_spots, pd.DataFrame)
self.assertIsInstance(df_intensities, pd.DataFrame)
df_results = pred[0]
segmentation_result = pred[1]
self.assertIsInstance(df_results, pd.DataFrame)
self.assertIsInstance(segmentation_result, np.ndarray)
self.assertAllEqual(segmentation_image.shape, segmentation_result.shape)
self.assertEqual(len(df_spots), len(df_intensities))
self.assertAllEqual(df_spots.probability, [None]*len(df_spots))
self.assertAllEqual(df_spots.predicted_id, [None]*len(df_spots))
self.assertAllEqual(df_spots.predicted_name, [None]*len(df_spots))
self.assertAllEqual(df_results.probability, [None]*len(df_results))
self.assertAllEqual(df_results.predicted_id, [None]*len(df_results))
self.assertAllEqual(df_results.predicted_name, [None]*len(df_results))

# test prediction type -- multivariate Gaussian
df_barcodes = pd.DataFrame(
Expand Down Expand Up @@ -259,14 +254,11 @@ def test_polaris_app(self):
pred = app.predict(spots_image=spots_image,
segmentation_image=segmentation_image,
background_image=background_image)
df_spots = pred[0]
df_intensities = pred[1]
segmentation_result = pred[2]
self.assertIsInstance(df_spots, pd.DataFrame)
self.assertIsInstance(df_intensities, pd.DataFrame)
df_results = pred[0]
segmentation_result = pred[1]
self.assertIsInstance(df_results, pd.DataFrame)
self.assertIsInstance(segmentation_result, np.ndarray)
self.assertAllEqual(segmentation_image.shape, segmentation_result.shape)
self.assertEqual(len(df_spots), len(df_intensities))

# test prediction type -- Bernoulli
df_barcodes = pd.DataFrame(
Expand Down Expand Up @@ -294,12 +286,9 @@ def test_polaris_app(self):
pred = app.predict(spots_image=spots_image,
segmentation_image=segmentation_image,
background_image=background_image)
df_spots = pred[0]
df_intensities = pred[1]
segmentation_result = pred[2]
self.assertIsInstance(df_spots, pd.DataFrame)
self.assertIsInstance(df_intensities, pd.DataFrame)
df_results = pred[0]
segmentation_result = pred[1]
self.assertIsInstance(df_results, pd.DataFrame)
self.assertIsInstance(segmentation_result, np.ndarray)
self.assertAllEqual(segmentation_image.shape, segmentation_result.shape)
self.assertEqual(len(df_spots), len(df_intensities))
self.assertAllInRange(df_spots.probability, 0, 1)
self.assertAllInRange(df_results.probability, 0, 1)

0 comments on commit c3a01d8

Please sign in to comment.