waveorder 2.2.1__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. waveorder/_version.py +16 -3
  2. waveorder/acq/__init__.py +0 -0
  3. waveorder/acq/acq_functions.py +166 -0
  4. waveorder/assets/HSV_legend.png +0 -0
  5. waveorder/assets/JCh_legend.png +0 -0
  6. waveorder/assets/waveorder_plugin_logo.png +0 -0
  7. waveorder/calib/Calibration.py +1512 -0
  8. waveorder/calib/Optimization.py +470 -0
  9. waveorder/calib/__init__.py +0 -0
  10. waveorder/calib/calibration_workers.py +464 -0
  11. waveorder/cli/apply_inverse_models.py +328 -0
  12. waveorder/cli/apply_inverse_transfer_function.py +379 -0
  13. waveorder/cli/compute_transfer_function.py +432 -0
  14. waveorder/cli/gui_widget.py +58 -0
  15. waveorder/cli/main.py +39 -0
  16. waveorder/cli/monitor.py +163 -0
  17. waveorder/cli/option_eat_all.py +47 -0
  18. waveorder/cli/parsing.py +122 -0
  19. waveorder/cli/printing.py +16 -0
  20. waveorder/cli/reconstruct.py +67 -0
  21. waveorder/cli/settings.py +187 -0
  22. waveorder/cli/utils.py +175 -0
  23. waveorder/filter.py +1 -2
  24. waveorder/focus.py +136 -25
  25. waveorder/io/__init__.py +0 -0
  26. waveorder/io/_reader.py +61 -0
  27. waveorder/io/core_functions.py +272 -0
  28. waveorder/io/metadata_reader.py +195 -0
  29. waveorder/io/utils.py +175 -0
  30. waveorder/io/visualization.py +160 -0
  31. waveorder/models/inplane_oriented_thick_pol3d_vector.py +3 -3
  32. waveorder/models/isotropic_fluorescent_thick_3d.py +92 -0
  33. waveorder/models/isotropic_fluorescent_thin_3d.py +331 -0
  34. waveorder/models/isotropic_thin_3d.py +73 -72
  35. waveorder/models/phase_thick_3d.py +103 -4
  36. waveorder/napari.yaml +36 -0
  37. waveorder/plugin/__init__.py +9 -0
  38. waveorder/plugin/gui.py +1094 -0
  39. waveorder/plugin/gui.ui +1440 -0
  40. waveorder/plugin/job_manager.py +42 -0
  41. waveorder/plugin/main_widget.py +1605 -0
  42. waveorder/plugin/tab_recon.py +3294 -0
  43. waveorder/scripts/__init__.py +0 -0
  44. waveorder/scripts/launch_napari.py +13 -0
  45. waveorder/scripts/repeat-cal-acq-rec.py +147 -0
  46. waveorder/scripts/repeat-calibration.py +31 -0
  47. waveorder/scripts/samples.py +85 -0
  48. waveorder/scripts/simulate_zarr_acq.py +204 -0
  49. waveorder/util.py +1 -1
  50. waveorder/visuals/napari_visuals.py +1 -1
  51. waveorder-3.0.0.dist-info/METADATA +350 -0
  52. waveorder-3.0.0.dist-info/RECORD +69 -0
  53. {waveorder-2.2.1.dist-info → waveorder-3.0.0.dist-info}/WHEEL +1 -1
  54. waveorder-3.0.0.dist-info/entry_points.txt +5 -0
  55. {waveorder-2.2.1.dist-info → waveorder-3.0.0.dist-info}/licenses/LICENSE +13 -1
  56. waveorder-2.2.1.dist-info/METADATA +0 -188
  57. waveorder-2.2.1.dist-info/RECORD +0 -27
  58. {waveorder-2.2.1.dist-info → waveorder-3.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,470 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+ from scipy import optimize
5
+
6
+
7
+ class BrentOptimizer:
8
+ def __init__(self, calib):
9
+ self.calib = calib
10
+
11
+ def _check_bounds(self, lca_bound, lcb_bound):
12
+ current_lca = self.calib.get_lc("LCA")
13
+ current_lcb = self.calib.get_lc("LCB")
14
+
15
+ # check that bounds don't exceed range of LC
16
+ lca_lower_bound = (
17
+ 0.01
18
+ if (current_lca - lca_bound) <= 0.01
19
+ else current_lca - lca_bound
20
+ )
21
+ lca_upper_bound = (
22
+ 1.6
23
+ if (current_lca + lca_bound) >= 1.6
24
+ else current_lca + lca_bound
25
+ )
26
+
27
+ lcb_lower_bound = (
28
+ 0.01
29
+ if current_lcb - lcb_bound <= 0.01
30
+ else current_lcb - lcb_bound
31
+ )
32
+ lcb_upper_bound = (
33
+ 1.6 if current_lcb + lcb_bound >= 1.6 else current_lcb + lcb_bound
34
+ )
35
+
36
+ return (
37
+ lca_lower_bound,
38
+ lca_upper_bound,
39
+ lcb_lower_bound,
40
+ lcb_upper_bound,
41
+ )
42
+
43
+ def opt_lca(
44
+ self,
45
+ cost_function,
46
+ lower_bound,
47
+ upper_bound,
48
+ reference,
49
+ cost_function_args,
50
+ ):
51
+ xopt, fval, ierr, numfunc = optimize.fminbound(
52
+ cost_function,
53
+ x1=lower_bound,
54
+ x2=upper_bound,
55
+ disp=0,
56
+ args=cost_function_args,
57
+ full_output=True,
58
+ )
59
+
60
+ lca = xopt
61
+ lcb = self.calib.get_lc(self.calib.mmc, self.calib.PROPERTIES["LCA"])
62
+ abs_intensity = fval + reference
63
+ difference = fval / reference * 100
64
+
65
+ logging.debug("\tOptimize lca ...")
66
+ logging.debug(f"\tlca = {lca:.5f}")
67
+ logging.debug(f"\tlcb = {lcb:.5f}")
68
+ logging.debug(f"\tIntensity = {abs_intensity}")
69
+ logging.debug(f"\tIntensity Difference = {difference:.4f}%")
70
+
71
+ return [lca, lcb, abs_intensity, difference]
72
+
73
+ def opt_lcb(
74
+ self,
75
+ cost_function,
76
+ lower_bound,
77
+ upper_bound,
78
+ reference,
79
+ cost_function_args,
80
+ ):
81
+ xopt, fval, ierr, numfunc = optimize.fminbound(
82
+ cost_function,
83
+ x1=lower_bound,
84
+ x2=upper_bound,
85
+ disp=0,
86
+ args=cost_function_args,
87
+ full_output=True,
88
+ )
89
+
90
+ lca = self.calib.get_lc(self.calib.mmc, self.calib.PROPERTIES["LCA"])
91
+ lcb = xopt
92
+ abs_intensity = fval + reference
93
+ difference = fval / reference * 100
94
+
95
+ logging.debug("\tOptimize lcb ...")
96
+ logging.debug(f"\tlca = {lca:.5f}")
97
+ logging.debug(f"\tlcb = {lcb:.5f}")
98
+ logging.debug(f"\tIntensity = {abs_intensity}")
99
+ logging.debug(f"\tIntensity Difference = {difference:.4f}%")
100
+
101
+ return [lca, lcb, abs_intensity, difference]
102
+
103
+ def optimize(self, state, lca_bound, lcb_bound, reference, thresh, n_iter):
104
+ converged = False
105
+ iteration = 1
106
+ self.calib.inten = []
107
+ optimal = []
108
+
109
+ while not converged:
110
+ logging.debug(f"iteration: {iteration}")
111
+
112
+ (
113
+ lca_lower_bound,
114
+ lca_upper_bound,
115
+ lcb_lower_bound,
116
+ lcb_upper_bound,
117
+ ) = self._check_bounds(lca_bound, lcb_bound)
118
+
119
+ if state == "ext":
120
+ results_lca = self.opt_lca(
121
+ self.calib.opt_lc,
122
+ lca_lower_bound,
123
+ lca_upper_bound,
124
+ reference,
125
+ (self.calib.PROPERTIES["LCA"], reference),
126
+ )
127
+
128
+ self.calib.set_lc(self.calib.mmc, results_lca[0], "LCA")
129
+
130
+ optimal.append(results_lca)
131
+
132
+ results_lcb = self.opt_lcb(
133
+ self.calib.opt_lc,
134
+ lcb_lower_bound,
135
+ lcb_upper_bound,
136
+ reference,
137
+ (self.calib.PROPERTIES["LCB"], reference),
138
+ )
139
+
140
+ self.calib.set_lc(self.calib.mmc, results_lca[1], "LCB")
141
+
142
+ optimal.append(results_lcb)
143
+
144
+ results = results_lcb
145
+
146
+ if state == "45" or state == "135":
147
+ results = self.opt_lcb(
148
+ self.calib.opt_lc,
149
+ lca_lower_bound,
150
+ lca_upper_bound,
151
+ reference,
152
+ (self.calib.PROPERTIES["LCB"], reference),
153
+ )
154
+
155
+ optimal.append(results)
156
+
157
+ if state == "60":
158
+ results = self.opt_lca(
159
+ self.calib.opt_lc_cons,
160
+ lca_lower_bound,
161
+ lca_upper_bound,
162
+ reference,
163
+ (reference, "60"),
164
+ )
165
+
166
+ swing = (self.calib.lca_ext - results[0]) * self.calib.ratio
167
+ lca = results[0]
168
+ lcb = self.calib.lcb_ext + swing
169
+
170
+ optimal.append([lca, lcb, results[2], results[3]])
171
+
172
+ if state == "90":
173
+ results = self.opt_lca(
174
+ self.calib.opt_lc,
175
+ lca_lower_bound,
176
+ lca_upper_bound,
177
+ reference,
178
+ (self.calib.PROPERTIES["LCA"], reference),
179
+ )
180
+
181
+ optimal.append(results)
182
+
183
+ if state == "120":
184
+ results = self.opt_lca(
185
+ self.calib.opt_lc_cons,
186
+ lca_lower_bound,
187
+ lca_upper_bound,
188
+ reference,
189
+ (reference, "120"),
190
+ )
191
+
192
+ swing = (self.calib.lca_ext - results[0]) * self.calib.ratio
193
+ lca = results[0]
194
+ lcb = self.calib.lcb_ext - swing
195
+
196
+ optimal.append([lca, lcb, results[2], results[3]])
197
+
198
+ # if both LCA and LCB meet threshold, stop
199
+ if results[3] <= thresh:
200
+ converged = True
201
+ optimal = np.asarray(optimal)
202
+
203
+ return optimal[-1, 0], optimal[-1, 1], optimal[-1, 2]
204
+
205
+ # if loop preforms more than n_iter iterations, stop
206
+ elif iteration >= n_iter:
207
+ logging.debug(
208
+ f"Exceeded {n_iter} Iterations: Search discontinuing"
209
+ )
210
+
211
+ converged = True
212
+ optimal = np.asarray(optimal)
213
+ opt = np.where(optimal == np.min(np.abs(optimal[:, 0])))[0]
214
+
215
+ logging.debug(
216
+ f"Lowest Inten: {optimal[opt, 0]}, lca = {optimal[opt, 1]}, lcb = {optimal[opt, 2]}"
217
+ )
218
+
219
+ return optimal[-1, 0], optimal[-1, 1], optimal[-1, 2]
220
+
221
+ iteration += 1
222
+
223
+
224
+ class MinScalarOptimizer:
225
+ def __init__(self, calib):
226
+ self.calib = calib
227
+
228
+ def _check_bounds(self, lca_bound, lcb_bound):
229
+ current_lca = self.calib.get_lc("LCA")
230
+ current_lcb = self.calib.get_lc("LCB")
231
+
232
+ if self.calib.mode == "voltage":
233
+ # check that bounds don't exceed range of LC
234
+ lca_lower_bound = (
235
+ 0.01
236
+ if (current_lca - lca_bound) <= 0.01
237
+ else current_lca - lca_bound
238
+ )
239
+ lca_upper_bound = (
240
+ 2.2
241
+ if (current_lca + lca_bound) >= 2.2
242
+ else current_lca + lca_bound
243
+ )
244
+
245
+ lcb_lower_bound = (
246
+ 0.01
247
+ if current_lcb - lcb_bound <= 0.01
248
+ else current_lcb - lcb_bound
249
+ )
250
+ lcb_upper_bound = (
251
+ 2.2
252
+ if current_lcb + lcb_bound >= 2.2
253
+ else current_lcb + lcb_bound
254
+ )
255
+
256
+ else:
257
+ # check that bounds don't exceed range of LC
258
+ lca_lower_bound = (
259
+ 0.01
260
+ if (current_lca - lca_bound) <= 0.01
261
+ else current_lca - lca_bound
262
+ )
263
+ lca_upper_bound = (
264
+ 1.6
265
+ if (current_lca + lca_bound) >= 1.6
266
+ else current_lca + lca_bound
267
+ )
268
+
269
+ lcb_lower_bound = (
270
+ 0.01
271
+ if current_lcb - lcb_bound <= 0.01
272
+ else current_lcb - lcb_bound
273
+ )
274
+ lcb_upper_bound = (
275
+ 1.6
276
+ if current_lcb + lcb_bound >= 1.6
277
+ else current_lcb + lcb_bound
278
+ )
279
+
280
+ return (
281
+ lca_lower_bound,
282
+ lca_upper_bound,
283
+ lcb_lower_bound,
284
+ lcb_upper_bound,
285
+ )
286
+
287
+ def opt_lca(
288
+ self,
289
+ cost_function,
290
+ lower_bound,
291
+ upper_bound,
292
+ reference,
293
+ cost_function_args,
294
+ ):
295
+ res = optimize.minimize_scalar(
296
+ cost_function,
297
+ bounds=(lower_bound, upper_bound),
298
+ method="bounded",
299
+ args=cost_function_args,
300
+ )
301
+
302
+ lca = res.x
303
+ lcb = self.calib.get_lc("LCB")
304
+ abs_intensity = res.fun + reference
305
+ difference = res.fun / reference * 100
306
+
307
+ logging.debug("\tOptimize lca ...")
308
+ logging.debug(f"\tlca = {lca:.5f}")
309
+ logging.debug(f"\tlcb = {lcb:.5f}")
310
+ logging.debug(f"\tIntensity = {abs_intensity}")
311
+ logging.debug(f"\tIntensity Difference = {difference:.4f}%")
312
+
313
+ return [lca, lcb, abs_intensity, difference]
314
+
315
+ def opt_lcb(
316
+ self,
317
+ cost_function,
318
+ lower_bound,
319
+ upper_bound,
320
+ reference,
321
+ cost_function_args,
322
+ ):
323
+ res = optimize.minimize_scalar(
324
+ cost_function,
325
+ bounds=(lower_bound, upper_bound),
326
+ method="bounded",
327
+ args=cost_function_args,
328
+ )
329
+
330
+ lca = self.calib.get_lc("LCA")
331
+ lcb = res.x
332
+ abs_intensity = res.fun + reference
333
+ difference = res.fun / reference * 100
334
+
335
+ logging.debug("\tOptimize lcb ...")
336
+ logging.debug(f"\tlca = {lca:.5f}")
337
+ logging.debug(f"\tlcb = {lcb:.5f}")
338
+ logging.debug(f"\tIntensity = {abs_intensity}")
339
+ logging.debug(f"\tIntensity Difference = {difference:.4f}%")
340
+
341
+ return [lca, lcb, abs_intensity, difference]
342
+
343
+ def optimize(
344
+ self, state, lca_bound, lcb_bound, reference, thresh=None, n_iter=None
345
+ ):
346
+ (
347
+ lca_lower_bound,
348
+ lca_upper_bound,
349
+ lcb_lower_bound,
350
+ lcb_upper_bound,
351
+ ) = self._check_bounds(lca_bound, lcb_bound)
352
+
353
+ if state == "ext":
354
+ optimal = []
355
+
356
+ results_lca = self.opt_lca(
357
+ self.calib.opt_lc,
358
+ lca_lower_bound,
359
+ lca_upper_bound,
360
+ reference,
361
+ ("LCA", reference),
362
+ )
363
+
364
+ self.calib.set_lc(results_lca[0], "LCA")
365
+
366
+ optimal.append(results_lca)
367
+
368
+ results_lcb = self.opt_lcb(
369
+ self.calib.opt_lc,
370
+ lcb_lower_bound,
371
+ lcb_upper_bound,
372
+ reference,
373
+ ("LCB", reference),
374
+ )
375
+
376
+ self.calib.set_lc(results_lcb[1], "LCB")
377
+
378
+ optimal.append(results_lcb)
379
+
380
+ # ============BEGIN FINE SEARCH=================
381
+
382
+ logging.debug(f"\n\tBeginning Finer Search\n")
383
+ lca_lower_bound = results_lcb[0] - 0.01
384
+ lca_upper_bound = results_lcb[0] + 0.01
385
+ lcb_lower_bound = results_lcb[1] - 0.01
386
+ lcb_upper_bound = results_lcb[1] + 0.01
387
+
388
+ results_lca = self.opt_lca(
389
+ self.calib.opt_lc,
390
+ lca_lower_bound,
391
+ lca_upper_bound,
392
+ reference,
393
+ ("LCA", reference),
394
+ )
395
+
396
+ self.calib.set_lc(results_lca[0], "LCA")
397
+
398
+ optimal.append(results_lca)
399
+
400
+ results_lcb = self.opt_lcb(
401
+ self.calib.opt_lc,
402
+ lcb_lower_bound,
403
+ lcb_upper_bound,
404
+ reference,
405
+ ("LCB", reference),
406
+ )
407
+
408
+ self.calib.set_lc(results_lcb[1], "LCB")
409
+
410
+ optimal.append(results_lcb)
411
+
412
+ # Sometimes this optimization can drift away from the minimum,
413
+ # this makes sure we use the lowest iteration
414
+ optimal = np.asarray(optimal)
415
+ opt = np.where(optimal == np.min(optimal[:][2]))[0]
416
+
417
+ lca = float(optimal[opt][0][0])
418
+ lcb = float(optimal[opt][0][1])
419
+ results = optimal[opt][0]
420
+
421
+ if state == "45" or state == "135":
422
+ results = self.opt_lcb(
423
+ self.calib.opt_lc,
424
+ lcb_lower_bound,
425
+ lcb_upper_bound,
426
+ reference,
427
+ ("LCB", reference),
428
+ )
429
+
430
+ lca = results[0]
431
+ lcb = results[1]
432
+
433
+ if state == "60":
434
+ results = self.opt_lca(
435
+ self.calib.opt_lc_cons,
436
+ lca_lower_bound,
437
+ lca_upper_bound,
438
+ reference,
439
+ ("LCA", reference, "60"),
440
+ )
441
+
442
+ swing = (self.calib.lca_ext - results[0]) * self.calib.ratio
443
+ lca = results[0]
444
+ lcb = self.calib.lcb_ext + swing
445
+
446
+ if state == "90":
447
+ results = self.opt_lca(
448
+ self.calib.opt_lc,
449
+ lca_lower_bound,
450
+ lca_upper_bound,
451
+ reference,
452
+ ("LCA", reference),
453
+ )
454
+ lca = results[0]
455
+ lcb = results[1]
456
+
457
+ if state == "120":
458
+ results = self.opt_lca(
459
+ self.calib.opt_lc_cons,
460
+ lca_lower_bound,
461
+ lca_upper_bound,
462
+ reference,
463
+ ("LCB", reference, "120"),
464
+ )
465
+
466
+ swing = (self.calib.lca_ext - results[0]) * self.calib.ratio
467
+ lca = results[0]
468
+ lcb = self.calib.lcb_ext - swing
469
+
470
+ return lca, lcb, results[2]
File without changes