Skip to content

Commit a9e98c6

Browse files
authored
Shannon Entropy: Convert to log2 and test (#184)
* Convert to log2 and test * Update intensity metric * Stable
1 parent 7e44edf commit a9e98c6

File tree

4 files changed

+66
-20
lines changed

4 files changed

+66
-20
lines changed

src/aslm/model/aslm_analysis.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,26 @@ def image_intensity(self, input_array, psf_support_diameter_xy):
7272
image_dimensions = input_array.ndim
7373

7474
if image_dimensions == 2:
75+
axes = (0, 1)
7576
(image_height, image_width) = input_array.shape
7677
number_of_images = 1
7778
elif image_dimensions == 3:
79+
axes = (1, 2)
7880
(number_of_images, image_height, image_width) = input_array.shape
7981
else:
8082
raise ValueError("Only 2D and 3D Images Supported.")
8183

8284
# Preallocate Array
8385
entropy = np.zeros(number_of_images)
8486

85-
for image_idx in range(int(number_of_images)):
86-
# Add entropy value to the entropy array
87-
entropy[image_idx] = np.sum(input_array[image_idx,...])
87+
s = np.prod([input_array.shape[x]**2 / psf_support_diameter_xy for x in axes])
88+
89+
if number_of_images == 1:
90+
entropy[0] = np.sum(input_array)/s
91+
else:
92+
for image_idx in range(int(number_of_images)):
93+
# Add entropy value to the entropy array
94+
entropy[image_idx] = np.sum(input_array[image_idx,...])/s
8895

8996
return entropy
9097

@@ -150,21 +157,16 @@ def normalized_dct_shannon_entropy(self,
150157
return entropy
151158

152159
def fast_normalized_dct_shannon_entropy(self,
153-
input_array,
154-
psf_support_diameter_xy):
155-
156-
axes = (0, 1)
157-
sl = slice(None)
158-
if input_array.ndim > 2:
159-
axes = (1, 2)
160-
sl = (slice(None), np.newaxis, np.newaxis)
160+
input_array,
161+
psf_support_diameter_xy):
161162

162-
dct_array = dctn(input_array, type=2, axes=axes)
163-
abs_array = np.abs(dct_array / np.atleast_1d(np.linalg.norm(dct_array, axis=axes))[sl])
164-
image_entropy = -2 * np.nansum(abs_array * np.log(abs_array), axis=axes) \
165-
/ np.prod([input_array.shape[x] / psf_support_diameter_xy for x in axes])
163+
dct_array = dctn(input_array, type=2)
164+
abs_array = np.abs(dct_array / np.linalg.norm(dct_array))
165+
yh = int(input_array.shape[1]//psf_support_diameter_xy)
166+
xh = int(input_array.shape[0]//psf_support_diameter_xy)
167+
entropy = -2*np.nansum(abs_array[:xh,:yh]*np.log2(abs_array[:xh,:yh]))/(yh*xh)
166168

167-
return np.atleast_1d(image_entropy)
169+
return np.atleast_1d(entropy)
168170

169171
def estimate_image_resolution(self,
170172
input_array,

src/aslm/model/devices/daq/daq_base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ def update_etl_parameters(self, microscope_state, channel, galvo_parameters, rea
282282
Duration of time necessary to readout a camera frame.
283283
"""
284284
laser, resolution_mode, zoom = channel['laser'], microscope_state['resolution_mode'], microscope_state['zoom']
285+
if resolution_mode == 'high':
286+
# TODO: Temporary hard code because I don't want to chase down why the dictionaries are getting
287+
# passed out of order again.
288+
zoom = 'N/A'
285289
remote_focus_dict = self.etl_constants.ETLConstants[resolution_mode][zoom][laser]
286290

287291
# Use defaults of 0 in the case they are not provided

src/aslm/model/model_features/autofocus.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ def get_steps(self, ranges, step_size):
118118
def pre_func_signal(self):
119119
settings = self.model.experiment.AutoFocusParameters
120120
# self.focus_pos = args[2] # Current position
121-
# self.focus_pos = self.model.focus_pos # TODO: get focus position from model right now.
122-
self.focus_pos = self.model.get_stage_position()['f_pos']
121+
self.focus_pos = self.model.focus_pos # TODO: get focus position from model right now.
122+
# self.focus_pos = self.model.get_stage_position()['f_pos']
123123
self.total_frame_num = self.get_autofocus_frame_num() #total frame num
124124
self.coarse_steps, self.init_pos = 0, 0
125125
if settings['fine_selected']:
@@ -184,7 +184,7 @@ def in_func_data(self, frame_ids=[]):
184184

185185
# print('entropy:', self.f_frame_id, self.frame_num, self.f_pos, entropy)
186186

187-
self.model.logger.debug(f'Appending plot data focus, entropy: {self.f_pos}, {entropy}')
187+
self.model.logger.debug(f'Appending plot data for frame {self.f_frame_id} focus: {self.f_pos}, entropy: {entropy[0]}')
188188
self.plot_data.append([self.f_pos, entropy[0]])
189189
# Need to initialize entropy above for the first iteration of the autofocus routine.
190190
# Need to initialize entropy_vector above for the first iteration of the autofocus routine.

test/model/test_aslm_analysis.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,52 @@
4141
# Local Imports
4242
# sys.path.append('../../../')
4343

44+
def box(size):
45+
x = np.linspace(0,1,100)
46+
X, Y = np.meshgrid(x,x)
47+
l = (1-size)/2
48+
u = l + size
49+
image = (X > l) & (X < u) & (Y > l) & (Y < u)
50+
return image.astype(float)
51+
52+
def power_tent(r, off, scale, sigma, alpha):
53+
return off + scale*(1-np.abs(sigma*r)**alpha)
54+
55+
def power_tent_res(x, r, val):
56+
return power_tent(r, *x)-val
57+
58+
def rsq(res_func, x, r, val):
59+
ss_err = (res_func(x,r,val)**2).sum()
60+
ss_tot = ((val-val.mean())**2).sum()
61+
rsq = 1 - (ss_err/ss_tot)
62+
return rsq
63+
64+
def test_fast_normalized_dct_shannon_entropy_tent():
65+
from scipy.ndimage import gaussian_filter
66+
from scipy.optimize import least_squares
67+
68+
from aslm.model.aslm_analysis import Analysis
69+
70+
anal = Analysis()
71+
72+
im = box(0.5)
73+
74+
r = range(0,60)
75+
points = np.zeros((len(r),))
76+
for i in r:
77+
points[i] = anal.fast_normalized_dct_shannon_entropy(gaussian_filter(im,i),1)[0]
78+
79+
res = least_squares(power_tent_res, [np.min(points),np.max(points),1,0.5], args=(r,points))
80+
81+
assert(rsq(power_tent_res, res.x, r, points) > 0.9)
82+
4483
def test_fast_normalized_dct_shannon_entropy():
4584
from aslm.model.aslm_analysis import Analysis
4685

4786
anal = Analysis()
4887

49-
image_array = np.ones((np.random.randint(1,4),128,128)).squeeze()
88+
# image_array = np.ones((np.random.randint(1,4),128,128)).squeeze()
89+
image_array = np.ones((128, 128)).squeeze()
5090
psf_support_diameter_xy = np.random.randint(3, 10)
5191

5292
entropy = anal.fast_normalized_dct_shannon_entropy(image_array, psf_support_diameter_xy)

0 commit comments

Comments
 (0)