waveorder 3.0.0a2__py3-none-any.whl → 3.0.0a3__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.
- waveorder/_version.py +2 -2
- waveorder/assets/waveorder_plugin_logo.png +0 -0
- waveorder/cli/apply_inverse_models.py +14 -10
- waveorder/cli/apply_inverse_transfer_function.py +3 -3
- waveorder/cli/compute_transfer_function.py +9 -7
- waveorder/cli/printing.py +6 -2
- waveorder/cli/settings.py +51 -51
- waveorder/cli/utils.py +1 -1
- waveorder/focus.py +73 -9
- waveorder/io/utils.py +5 -3
- waveorder/models/phase_thick_3d.py +103 -4
- waveorder/plugin/gui.py +198 -799
- waveorder/plugin/gui.ui +0 -795
- waveorder/plugin/main_widget.py +6 -572
- waveorder/plugin/tab_recon.py +196 -96
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/METADATA +18 -3
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/RECORD +21 -22
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/WHEEL +1 -1
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/licenses/LICENSE +12 -0
- waveorder/acq/acquisition_workers.py +0 -650
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/entry_points.txt +0 -0
- {waveorder-3.0.0a2.dist-info → waveorder-3.0.0a3.dist-info}/top_level.txt +0 -0
waveorder/plugin/main_widget.py
CHANGED
|
@@ -35,13 +35,6 @@ try:
|
|
|
35
35
|
except:
|
|
36
36
|
pass
|
|
37
37
|
|
|
38
|
-
try:
|
|
39
|
-
from waveorder.acq.acquisition_workers import (
|
|
40
|
-
BFAcquisitionWorker,
|
|
41
|
-
PolarizationAcquisitionWorker,
|
|
42
|
-
)
|
|
43
|
-
except:
|
|
44
|
-
pass
|
|
45
38
|
from waveorder.calib import Calibration
|
|
46
39
|
from waveorder.calib.Calibration import LC_DEVICE_NAME, QLIPP_Calibration
|
|
47
40
|
from waveorder.calib.calibration_workers import (
|
|
@@ -71,25 +64,6 @@ class MainWidget(QWidget):
|
|
|
71
64
|
|
|
72
65
|
# Initialize class attributes
|
|
73
66
|
disabled_button_style = "border: 1px solid rgb(65,72,81);"
|
|
74
|
-
bf_keywords = [
|
|
75
|
-
"bf",
|
|
76
|
-
"brightfield",
|
|
77
|
-
"bright",
|
|
78
|
-
"labelfree",
|
|
79
|
-
"label-free",
|
|
80
|
-
"lf",
|
|
81
|
-
"label",
|
|
82
|
-
"phase",
|
|
83
|
-
"ph",
|
|
84
|
-
]
|
|
85
|
-
no_bf_msg = "\n".join(
|
|
86
|
-
textwrap.wrap(
|
|
87
|
-
f"No brightfield channel found. If you would like to acquire phase from brightfield,"
|
|
88
|
-
" please restart waveorder after adding a new channel to Micro-Manager with one of the"
|
|
89
|
-
" following case-insensitive keywords: " + ", ".join(bf_keywords),
|
|
90
|
-
width=70,
|
|
91
|
-
)
|
|
92
|
-
)
|
|
93
67
|
|
|
94
68
|
def __init__(self, napari_viewer: Viewer):
|
|
95
69
|
super().__init__()
|
|
@@ -103,9 +77,6 @@ class MainWidget(QWidget):
|
|
|
103
77
|
# Override initial tab focus
|
|
104
78
|
self.ui.tabWidget.setCurrentIndex(0)
|
|
105
79
|
|
|
106
|
-
# Set attributes need for enabling/disabling buttons
|
|
107
|
-
self.bf_channel_found = False
|
|
108
|
-
|
|
109
80
|
# Disable buttons until connected to MM
|
|
110
81
|
self._set_buttons_enabled(False)
|
|
111
82
|
|
|
@@ -158,88 +129,6 @@ class MainWidget(QWidget):
|
|
|
158
129
|
)
|
|
159
130
|
self.ui.qbutton_push_note.clicked[bool].connect(self.push_note)
|
|
160
131
|
|
|
161
|
-
# Acquisition tab
|
|
162
|
-
self.ui.qbutton_browse_save_dir.clicked[bool].connect(
|
|
163
|
-
self.browse_save_path
|
|
164
|
-
)
|
|
165
|
-
self.ui.le_save_dir.editingFinished.connect(self.enter_save_path)
|
|
166
|
-
self.ui.le_save_dir.setText(str(Path.cwd()))
|
|
167
|
-
self.ui.le_data_save_name.editingFinished.connect(self.enter_save_name)
|
|
168
|
-
|
|
169
|
-
self.ui.le_zstart.editingFinished.connect(self.enter_zstart)
|
|
170
|
-
self.ui.le_zstart.setText("-10")
|
|
171
|
-
self.enter_zstart()
|
|
172
|
-
|
|
173
|
-
self.ui.le_zend.editingFinished.connect(self.enter_zend)
|
|
174
|
-
self.ui.le_zend.setText("10")
|
|
175
|
-
self.enter_zend()
|
|
176
|
-
|
|
177
|
-
self.ui.le_zstep.editingFinished.connect(self.enter_zstep)
|
|
178
|
-
self.ui.le_zstep.setText("1")
|
|
179
|
-
self.enter_zstep()
|
|
180
|
-
|
|
181
|
-
self.ui.chb_use_gpu.stateChanged[int].connect(self.enter_use_gpu)
|
|
182
|
-
self.ui.le_gpu_id.editingFinished.connect(self.enter_gpu_id)
|
|
183
|
-
|
|
184
|
-
self.ui.cb_rotate_orientation.stateChanged[int].connect(
|
|
185
|
-
self.enter_rotate_orientation
|
|
186
|
-
)
|
|
187
|
-
self.ui.cb_flip_orientation.stateChanged[int].connect(
|
|
188
|
-
self.enter_flip_orientation
|
|
189
|
-
)
|
|
190
|
-
self.ui.cb_invert_phase_contrast.stateChanged[int].connect(
|
|
191
|
-
self.enter_invert_phase_contrast
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
# This parameter seems to be wired differently than others...investigate later
|
|
195
|
-
self.ui.le_recon_wavelength.editingFinished.connect(
|
|
196
|
-
self.enter_recon_wavelength
|
|
197
|
-
)
|
|
198
|
-
self.ui.le_recon_wavelength.setText("532")
|
|
199
|
-
self.enter_recon_wavelength()
|
|
200
|
-
|
|
201
|
-
self.ui.le_obj_na.editingFinished.connect(self.enter_obj_na)
|
|
202
|
-
self.ui.le_obj_na.setText("1.3")
|
|
203
|
-
self.enter_obj_na()
|
|
204
|
-
|
|
205
|
-
self.ui.le_cond_na.editingFinished.connect(self.enter_cond_na)
|
|
206
|
-
self.ui.le_cond_na.setText("0.5")
|
|
207
|
-
self.enter_cond_na()
|
|
208
|
-
|
|
209
|
-
self.ui.le_mag.editingFinished.connect(self.enter_mag)
|
|
210
|
-
self.ui.le_mag.setText("60")
|
|
211
|
-
self.enter_mag()
|
|
212
|
-
|
|
213
|
-
self.ui.le_ps.editingFinished.connect(self.enter_ps)
|
|
214
|
-
self.ui.le_ps.setText("6.9")
|
|
215
|
-
self.enter_ps()
|
|
216
|
-
|
|
217
|
-
self.ui.le_n_media.editingFinished.connect(self.enter_n_media)
|
|
218
|
-
self.ui.le_n_media.setText("1.3")
|
|
219
|
-
self.enter_n_media()
|
|
220
|
-
|
|
221
|
-
self.ui.le_pad_z.editingFinished.connect(self.enter_pad_z)
|
|
222
|
-
self.ui.cb_acq_mode.currentIndexChanged[int].connect(
|
|
223
|
-
self.enter_acq_mode
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
self.ui.cb_bg_method.currentIndexChanged[int].connect(
|
|
227
|
-
self.enter_bg_correction
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
self.ui.le_bg_path.editingFinished.connect(self.enter_acq_bg_path)
|
|
231
|
-
self.ui.qbutton_browse_bg_path.clicked[bool].connect(
|
|
232
|
-
self.browse_acq_bg_path
|
|
233
|
-
)
|
|
234
|
-
self.ui.qbutton_acq_ret_ori.clicked[bool].connect(self.acq_ret_ori)
|
|
235
|
-
self.ui.qbutton_acq_phase_from_bf.clicked[bool].connect(
|
|
236
|
-
self.acq_phase_from_bf
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
self.ui.qbutton_acq_ret_ori_phase.clicked[bool].connect(
|
|
240
|
-
self.acq_ret_ori_phase
|
|
241
|
-
)
|
|
242
|
-
|
|
243
132
|
# hook to render overlay
|
|
244
133
|
# acquistion updates existing layers and moves them to the top which triggers this event
|
|
245
134
|
self.viewer.layers.events.moved.connect(self.handle_layers_updated)
|
|
@@ -250,12 +139,6 @@ class MainWidget(QWidget):
|
|
|
250
139
|
self.handle_ret_max_slider_move
|
|
251
140
|
)
|
|
252
141
|
|
|
253
|
-
# Reconstruction tab
|
|
254
|
-
self.ui.cb_phase_denoiser.currentIndexChanged[int].connect(
|
|
255
|
-
self.enter_phase_denoiser
|
|
256
|
-
)
|
|
257
|
-
self.enter_phase_denoiser()
|
|
258
|
-
|
|
259
142
|
## Initialize logging
|
|
260
143
|
log_box = QtLogger(self.ui.te_log)
|
|
261
144
|
log_box.setFormatter(logging.Formatter("%(levelname)s - %(message)s"))
|
|
@@ -269,8 +152,6 @@ class MainWidget(QWidget):
|
|
|
269
152
|
self.mmc = None
|
|
270
153
|
self.calib = None
|
|
271
154
|
self.current_dir_path = str(Path.cwd())
|
|
272
|
-
self.current_save_path = str(Path.cwd())
|
|
273
|
-
self.current_bg_path = str(Path.cwd())
|
|
274
155
|
self.directory = str(Path.cwd())
|
|
275
156
|
self.calib_scheme = "4-State"
|
|
276
157
|
self.calib_mode = "MM-Retardance"
|
|
@@ -288,18 +169,6 @@ class MainWidget(QWidget):
|
|
|
288
169
|
self.bg_folder_name = "bg"
|
|
289
170
|
self.n_avg = 5
|
|
290
171
|
self.intensity_monitor = []
|
|
291
|
-
self.save_directory = str(Path.cwd())
|
|
292
|
-
self.save_name = None
|
|
293
|
-
self.bg_option = "None"
|
|
294
|
-
self.acq_mode = "2D"
|
|
295
|
-
self.gpu_id = 0
|
|
296
|
-
self.use_gpu = False
|
|
297
|
-
self.rotate_orientation = False
|
|
298
|
-
self.flip_orientation = False
|
|
299
|
-
self.invert_phase_contrast = False
|
|
300
|
-
self.pad_z = 0
|
|
301
|
-
self.phase_reconstructor = None
|
|
302
|
-
self.acq_bg_directory = ""
|
|
303
172
|
self.auto_shutter = True
|
|
304
173
|
self.lca_dac = None
|
|
305
174
|
self.lcb_dac = None
|
|
@@ -348,17 +217,6 @@ class MainWidget(QWidget):
|
|
|
348
217
|
self.ui.cb_lca.hide()
|
|
349
218
|
self.ui.cb_lcb.hide()
|
|
350
219
|
|
|
351
|
-
# Background correction popups
|
|
352
|
-
self.ui.label_bg_path.setHidden(True)
|
|
353
|
-
self.ui.le_bg_path.setHidden(True)
|
|
354
|
-
self.ui.qbutton_browse_bg_path.setHidden(True)
|
|
355
|
-
|
|
356
|
-
# Reconstruction parameter popups
|
|
357
|
-
self.ui.le_rho.setHidden(True)
|
|
358
|
-
self.ui.label_phase_rho.setHidden(True)
|
|
359
|
-
self.ui.le_itr.setHidden(True)
|
|
360
|
-
self.ui.label_itr.setHidden(True)
|
|
361
|
-
|
|
362
220
|
# Hide temporarily unsupported "Overlay" functions
|
|
363
221
|
self.ui.tabWidget.setTabText(
|
|
364
222
|
self.ui.tabWidget.indexOf(self.ui.Display), "Visualization"
|
|
@@ -379,23 +237,6 @@ class MainWidget(QWidget):
|
|
|
379
237
|
self.setStyleSheet("QTabWidget::tab-bar {alignment: center;}")
|
|
380
238
|
self.red_text = QColor(200, 0, 0, 255)
|
|
381
239
|
|
|
382
|
-
# Populate background correction GUI element
|
|
383
|
-
for i in range(3):
|
|
384
|
-
self.ui.cb_bg_method.removeItem(0)
|
|
385
|
-
bg_options = ["None", "Measured", "Estimated", "Measured + Estimated"]
|
|
386
|
-
tooltips = [
|
|
387
|
-
"No background correction.",
|
|
388
|
-
'Correct sample images with a background image acquired at an empty field of view, loaded from "Background Path".',
|
|
389
|
-
"Estimate sample background by fitting a 2D surface to the sample images. Works well when structures are spatially distributed across the field of view and a clear background is unavailable.",
|
|
390
|
-
'Apply "Measured" background correction and then "Estimated" background correction. Use to remove residual background after the sample retardance is corrected with measured background.',
|
|
391
|
-
]
|
|
392
|
-
for i, bg_option in enumerate(bg_options):
|
|
393
|
-
wrapped_tooltip = "\n".join(textwrap.wrap(tooltips[i], width=70))
|
|
394
|
-
self.ui.cb_bg_method.addItem(bg_option)
|
|
395
|
-
self.ui.cb_bg_method.setItemData(
|
|
396
|
-
i, wrapped_tooltip, Qt.ToolTipRole
|
|
397
|
-
)
|
|
398
|
-
|
|
399
240
|
# Populate calibration modes from docstring
|
|
400
241
|
cal_docs = NumpyDocString(
|
|
401
242
|
Calibration.QLIPP_Calibration.__init__.__doc__
|
|
@@ -409,15 +250,6 @@ class MainWidget(QWidget):
|
|
|
409
250
|
i, wrapped_tooltip, Qt.ToolTipRole
|
|
410
251
|
)
|
|
411
252
|
|
|
412
|
-
# Populate acquisition mode tooltips
|
|
413
|
-
acq_tooltips = [
|
|
414
|
-
"Acquires data to estimate parameters in a 2D plane. For birefringence acquisitions, this mode will acquire 2D data. For phase acquisitions, this mode will acquire 3D data.",
|
|
415
|
-
"Acquires 3D data to estimate parameters in a 3D volume.",
|
|
416
|
-
]
|
|
417
|
-
for i, tooltip in enumerate(acq_tooltips):
|
|
418
|
-
wrapped_tooltip = "\n".join(textwrap.wrap(tooltip, width=70))
|
|
419
|
-
self.ui.cb_acq_mode.setItemData(i, wrapped_tooltip, Qt.ToolTipRole)
|
|
420
|
-
|
|
421
253
|
# make sure the top says waveorder and not 'Form'
|
|
422
254
|
self.ui.tabWidget.parent().setObjectName("waveorder")
|
|
423
255
|
|
|
@@ -598,9 +430,6 @@ class MainWidget(QWidget):
|
|
|
598
430
|
self.ui.qbutton_calibrate,
|
|
599
431
|
self.ui.qbutton_capture_bg,
|
|
600
432
|
self.ui.qbutton_calc_extinction,
|
|
601
|
-
self.ui.qbutton_acq_ret_ori,
|
|
602
|
-
self.ui.qbutton_acq_phase_from_bf,
|
|
603
|
-
self.ui.qbutton_acq_ret_ori_phase,
|
|
604
433
|
self.ui.qbutton_load_calib,
|
|
605
434
|
self.ui.qbutton_create_overlay,
|
|
606
435
|
]
|
|
@@ -616,13 +445,6 @@ class MainWidget(QWidget):
|
|
|
616
445
|
)
|
|
617
446
|
action_button.setStyleSheet(self.disabled_button_style)
|
|
618
447
|
|
|
619
|
-
if not self.bf_channel_found:
|
|
620
|
-
self.ui.qbutton_acq_phase_from_bf.setEnabled(False)
|
|
621
|
-
self.ui.qbutton_acq_phase_from_bf.setStyleSheet(
|
|
622
|
-
self.disabled_button_style
|
|
623
|
-
)
|
|
624
|
-
self.ui.qbutton_acq_phase_from_bf.setToolTip(self.no_bf_msg)
|
|
625
|
-
|
|
626
448
|
def _enable_buttons(self):
|
|
627
449
|
self._set_buttons_enabled(True)
|
|
628
450
|
|
|
@@ -708,75 +530,6 @@ class MainWidget(QWidget):
|
|
|
708
530
|
le.setStyleSheet("")
|
|
709
531
|
return True
|
|
710
532
|
|
|
711
|
-
def _check_requirements_for_acq(self, mode):
|
|
712
|
-
"""
|
|
713
|
-
This function will loop through the parameters from a specific acquisition and make sure the user has
|
|
714
|
-
specified the necessary parameters. If it finds an empty or missing parameters, it will set missing fields red
|
|
715
|
-
and stop the acquisition process.
|
|
716
|
-
|
|
717
|
-
Parameters
|
|
718
|
-
----------
|
|
719
|
-
mode: (str) 'birefringence' or 'phase' which denotes the type of acquisition
|
|
720
|
-
|
|
721
|
-
Returns
|
|
722
|
-
-------
|
|
723
|
-
|
|
724
|
-
"""
|
|
725
|
-
# check if a QLIPP_Calibration object has been initialized
|
|
726
|
-
if mode != "phase" and not self.calib:
|
|
727
|
-
raise RuntimeError("Please run or load calibration first.")
|
|
728
|
-
|
|
729
|
-
# initialize the variable to keep track of the success of the requirement check
|
|
730
|
-
raise_error = False
|
|
731
|
-
|
|
732
|
-
# define the fields required for the specific acquisition modes. Matches LineEdit object names
|
|
733
|
-
phase_required = {
|
|
734
|
-
"recon_wavelength",
|
|
735
|
-
"wavelength",
|
|
736
|
-
"mag",
|
|
737
|
-
"cond_na",
|
|
738
|
-
"obj_na",
|
|
739
|
-
"n_media",
|
|
740
|
-
"phase_strength",
|
|
741
|
-
"ps",
|
|
742
|
-
"zstep",
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
# Initalize all fields in their default style (not red).
|
|
746
|
-
for field in phase_required:
|
|
747
|
-
le = getattr(self.ui, f"le_{field}")
|
|
748
|
-
le.setStyleSheet("")
|
|
749
|
-
|
|
750
|
-
# Check generally required fields
|
|
751
|
-
if mode == "birefringence" or mode == "phase":
|
|
752
|
-
success = self._check_line_edit("save_dir")
|
|
753
|
-
if not success:
|
|
754
|
-
raise_error = True
|
|
755
|
-
|
|
756
|
-
# check background path if 'Measured' or 'Measured + Estimated' is selected
|
|
757
|
-
if (
|
|
758
|
-
self.bg_option == "Measured"
|
|
759
|
-
or self.bg_option == "Measured + Estimated"
|
|
760
|
-
):
|
|
761
|
-
success = self._check_line_edit("bg_path")
|
|
762
|
-
if not success:
|
|
763
|
-
raise_error = True
|
|
764
|
-
|
|
765
|
-
# Check phase specific fields
|
|
766
|
-
if mode == "phase":
|
|
767
|
-
for field in phase_required:
|
|
768
|
-
cont = self._check_line_edit(field)
|
|
769
|
-
if not cont:
|
|
770
|
-
raise_error = True
|
|
771
|
-
else:
|
|
772
|
-
continue
|
|
773
|
-
|
|
774
|
-
# Alert the user to check and enter in the missing parameters
|
|
775
|
-
if raise_error:
|
|
776
|
-
raise ValueError(
|
|
777
|
-
"Please enter in all of the parameters necessary for the acquisition"
|
|
778
|
-
)
|
|
779
|
-
|
|
780
533
|
@Slot(bool)
|
|
781
534
|
def toggle_mm_connection(self):
|
|
782
535
|
"""
|
|
@@ -900,17 +653,6 @@ class MainWidget(QWidget):
|
|
|
900
653
|
config_group_found = True
|
|
901
654
|
self.ui.cb_config_group.addItem(group)
|
|
902
655
|
|
|
903
|
-
# Populate the acquisition "BF channel" list with presets that contain any of these keywords
|
|
904
|
-
for ch in config_list:
|
|
905
|
-
if any(
|
|
906
|
-
[
|
|
907
|
-
keyword.lower() in ch.lower()
|
|
908
|
-
for keyword in self.bf_keywords
|
|
909
|
-
]
|
|
910
|
-
):
|
|
911
|
-
self.ui.cb_acq_channel.addItem(ch)
|
|
912
|
-
self.bf_channel_found = True
|
|
913
|
-
|
|
914
656
|
logging.debug("Checked configs.")
|
|
915
657
|
if not config_group_found:
|
|
916
658
|
msg = (
|
|
@@ -922,18 +664,6 @@ class MainWidget(QWidget):
|
|
|
922
664
|
)
|
|
923
665
|
raise KeyError(msg)
|
|
924
666
|
|
|
925
|
-
if not self.bf_channel_found:
|
|
926
|
-
try:
|
|
927
|
-
self.ui.qbutton_acq_phase_from_bf.disconnect()
|
|
928
|
-
except Exception as exc:
|
|
929
|
-
print(exc.args)
|
|
930
|
-
logging.debug(exc.args)
|
|
931
|
-
self.ui.qbutton_acq_phase_from_bf.setStyleSheet(
|
|
932
|
-
self.disabled_button_style
|
|
933
|
-
)
|
|
934
|
-
self.ui.qbutton_acq_phase_from_bf.setToolTip(self.no_bf_msg)
|
|
935
|
-
self.ui.cb_acq_channel.setToolTip(self.no_bf_msg)
|
|
936
|
-
|
|
937
667
|
# set startup LC control mode
|
|
938
668
|
logging.debug("Setting startup LC control mode...")
|
|
939
669
|
_devices = self.mmc.getLoadedDevices()
|
|
@@ -1229,7 +959,12 @@ class MainWidget(QWidget):
|
|
|
1229
959
|
@Slot(tuple)
|
|
1230
960
|
def handle_phase_image_update(self, value):
|
|
1231
961
|
phase, scale = value
|
|
1232
|
-
|
|
962
|
+
# Determine name based on data dimensionality
|
|
963
|
+
name = (
|
|
964
|
+
"Phase2D"
|
|
965
|
+
if phase.ndim == 2 or (phase.ndim > 2 and phase.shape[0] == 1)
|
|
966
|
+
else "Phase3D"
|
|
967
|
+
)
|
|
1233
968
|
|
|
1234
969
|
# Add new layer if none exists, otherwise update layer data
|
|
1235
970
|
self._add_or_update_image_layer(phase, name, scale=scale)
|
|
@@ -1273,57 +1008,12 @@ class MainWidget(QWidget):
|
|
|
1273
1008
|
def handle_reconstruction_store_update(self, value):
|
|
1274
1009
|
self.reconstruction_data_path = value
|
|
1275
1010
|
|
|
1276
|
-
# This seems to be unused
|
|
1277
|
-
# @Slot(tuple)
|
|
1278
|
-
# def handle_reconstruction_dim_update(self, value):
|
|
1279
|
-
# p, t, c = value
|
|
1280
|
-
# layer_name = self.worker.manager.config.data_save_name
|
|
1281
|
-
|
|
1282
|
-
# if p == 0 and t == 0 and c == 0:
|
|
1283
|
-
# self.reconstruction_data = WaveorderReader(
|
|
1284
|
-
# self.reconstruction_data_path, "zarr"
|
|
1285
|
-
# )
|
|
1286
|
-
# self.viewer.add_image(
|
|
1287
|
-
# self.reconstruction_data.get_zarr(p),
|
|
1288
|
-
# name=layer_name + f"_Pos_{p:03d}",
|
|
1289
|
-
# )
|
|
1290
|
-
|
|
1291
|
-
# self.viewer.dims.set_axis_label(0, "T")
|
|
1292
|
-
# self.viewer.dims.set_axis_label(1, "C")
|
|
1293
|
-
# self.viewer.dims.set_axis_label(2, "Z")
|
|
1294
|
-
|
|
1295
|
-
# # Add each new position as a new layer in napari
|
|
1296
|
-
# name = layer_name + f"_Pos_{p:03d}"
|
|
1297
|
-
# if name not in self.viewer.layers:
|
|
1298
|
-
# self.reconstruction_data = WaveorderReader(
|
|
1299
|
-
# self.reconstruction_data_path, "zarr"
|
|
1300
|
-
# )
|
|
1301
|
-
# self.viewer.add_image(
|
|
1302
|
-
# self.reconstruction_data.get_zarr(p), name=name
|
|
1303
|
-
# )
|
|
1304
|
-
|
|
1305
|
-
# # update the napari dimension slider position if the user hasn't specified to pause updates
|
|
1306
|
-
# if not self.pause_updates:
|
|
1307
|
-
# self.viewer.dims.set_current_step(0, t)
|
|
1308
|
-
# self.viewer.dims.set_current_step(1, c)
|
|
1309
|
-
|
|
1310
|
-
# self.last_p = p
|
|
1311
|
-
|
|
1312
1011
|
@Slot(bool)
|
|
1313
1012
|
def browse_dir_path(self):
|
|
1314
1013
|
result = self._open_file_dialog(self.current_dir_path, "dir")
|
|
1315
1014
|
self.directory = result
|
|
1316
1015
|
self.current_dir_path = result
|
|
1317
1016
|
self.ui.le_directory.setText(result)
|
|
1318
|
-
self.ui.le_save_dir.setText(result)
|
|
1319
|
-
self.save_directory = result
|
|
1320
|
-
|
|
1321
|
-
@Slot(bool)
|
|
1322
|
-
def browse_save_path(self):
|
|
1323
|
-
result = self._open_file_dialog(self.current_save_path, "dir")
|
|
1324
|
-
self.save_directory = result
|
|
1325
|
-
self.current_save_path = result
|
|
1326
|
-
self.ui.le_save_dir.setText(result)
|
|
1327
1017
|
|
|
1328
1018
|
@Slot(bool)
|
|
1329
1019
|
def browse_data_dir(self):
|
|
@@ -1342,8 +1032,6 @@ class MainWidget(QWidget):
|
|
|
1342
1032
|
path = self.ui.le_directory.text()
|
|
1343
1033
|
if os.path.exists(path):
|
|
1344
1034
|
self.directory = path
|
|
1345
|
-
self.save_directory = path
|
|
1346
|
-
self.ui.le_save_dir.setText(path)
|
|
1347
1035
|
else:
|
|
1348
1036
|
self.ui.le_directory.setText("Path Does Not Exist")
|
|
1349
1037
|
|
|
@@ -1476,184 +1164,6 @@ class MainWidget(QWidget):
|
|
|
1476
1164
|
else:
|
|
1477
1165
|
logging.getLogger().setLevel(logging.DEBUG)
|
|
1478
1166
|
|
|
1479
|
-
@Slot()
|
|
1480
|
-
def enter_save_path(self):
|
|
1481
|
-
path = self.ui.le_save_dir.text()
|
|
1482
|
-
if os.path.exists(path):
|
|
1483
|
-
self.save_directory = path
|
|
1484
|
-
self.current_save_path = path
|
|
1485
|
-
else:
|
|
1486
|
-
self.ui.le_save_dir.setText("Path Does Not Exist")
|
|
1487
|
-
|
|
1488
|
-
@Slot()
|
|
1489
|
-
def enter_save_name(self):
|
|
1490
|
-
name = self.ui.le_data_save_name.text()
|
|
1491
|
-
self.save_name = name
|
|
1492
|
-
|
|
1493
|
-
@Slot()
|
|
1494
|
-
def enter_zstart(self):
|
|
1495
|
-
self.z_start = float(self.ui.le_zstart.text())
|
|
1496
|
-
|
|
1497
|
-
@Slot()
|
|
1498
|
-
def enter_zend(self):
|
|
1499
|
-
self.z_end = float(self.ui.le_zend.text())
|
|
1500
|
-
|
|
1501
|
-
@Slot()
|
|
1502
|
-
def enter_zstep(self):
|
|
1503
|
-
self.z_step = float(self.ui.le_zstep.text())
|
|
1504
|
-
|
|
1505
|
-
@Slot()
|
|
1506
|
-
def enter_acq_mode(self):
|
|
1507
|
-
state = self.ui.cb_acq_mode.currentIndex()
|
|
1508
|
-
if state == 0:
|
|
1509
|
-
self.acq_mode = "2D"
|
|
1510
|
-
elif state == 1:
|
|
1511
|
-
self.acq_mode = "3D"
|
|
1512
|
-
|
|
1513
|
-
@Slot()
|
|
1514
|
-
def enter_phase_denoiser(self):
|
|
1515
|
-
state = self.ui.cb_phase_denoiser.currentIndex()
|
|
1516
|
-
if state == 0:
|
|
1517
|
-
self.phase_regularizer = "Tikhonov"
|
|
1518
|
-
self.ui.label_itr.setHidden(True)
|
|
1519
|
-
self.ui.label_phase_rho.setHidden(True)
|
|
1520
|
-
self.ui.le_rho.setHidden(True)
|
|
1521
|
-
self.ui.le_itr.setHidden(True)
|
|
1522
|
-
|
|
1523
|
-
elif state == 1:
|
|
1524
|
-
self.phase_regularizer = "TV"
|
|
1525
|
-
self.ui.label_itr.setHidden(False)
|
|
1526
|
-
self.ui.label_phase_rho.setHidden(False)
|
|
1527
|
-
self.ui.le_rho.setHidden(False)
|
|
1528
|
-
self.ui.le_itr.setHidden(False)
|
|
1529
|
-
|
|
1530
|
-
@Slot()
|
|
1531
|
-
def enter_acq_bg_path(self):
|
|
1532
|
-
path = self.ui.le_bg_path.text()
|
|
1533
|
-
if os.path.exists(path):
|
|
1534
|
-
self.acq_bg_directory = path
|
|
1535
|
-
self.current_bg_path = path
|
|
1536
|
-
else:
|
|
1537
|
-
self.ui.le_bg_path.setText("Path Does Not Exist")
|
|
1538
|
-
|
|
1539
|
-
@Slot(Path)
|
|
1540
|
-
def handle_bg_path_update(self, value: Path):
|
|
1541
|
-
"""
|
|
1542
|
-
Handles the update of the most recent background folderpath from
|
|
1543
|
-
BackgroundWorker to display in the reconstruction texbox.
|
|
1544
|
-
|
|
1545
|
-
Parameters
|
|
1546
|
-
----------
|
|
1547
|
-
value : str
|
|
1548
|
-
most recent captured background folderpath
|
|
1549
|
-
"""
|
|
1550
|
-
path = value
|
|
1551
|
-
if path.exists():
|
|
1552
|
-
self.acq_bg_directory = path
|
|
1553
|
-
self.current_bg_path = path
|
|
1554
|
-
self.ui.le_bg_path.setText(str(path))
|
|
1555
|
-
else:
|
|
1556
|
-
msg = """
|
|
1557
|
-
Background acquisition was not successful.
|
|
1558
|
-
Check latest background capture saving directory!
|
|
1559
|
-
"""
|
|
1560
|
-
raise RuntimeError(msg)
|
|
1561
|
-
|
|
1562
|
-
@Slot(bool)
|
|
1563
|
-
def browse_acq_bg_path(self):
|
|
1564
|
-
result = self._open_file_dialog(self.current_bg_path, "dir")
|
|
1565
|
-
self.acq_bg_directory = result
|
|
1566
|
-
self.current_bg_path = result
|
|
1567
|
-
self.ui.le_bg_path.setText(result)
|
|
1568
|
-
|
|
1569
|
-
@Slot()
|
|
1570
|
-
def enter_bg_correction(self):
|
|
1571
|
-
state = self.ui.cb_bg_method.currentIndex()
|
|
1572
|
-
if state == 0:
|
|
1573
|
-
self.ui.label_bg_path.setHidden(True)
|
|
1574
|
-
self.ui.le_bg_path.setHidden(True)
|
|
1575
|
-
self.ui.qbutton_browse_bg_path.setHidden(True)
|
|
1576
|
-
self.bg_option = "None"
|
|
1577
|
-
elif state == 1:
|
|
1578
|
-
self.ui.label_bg_path.setHidden(False)
|
|
1579
|
-
self.ui.le_bg_path.setHidden(False)
|
|
1580
|
-
self.ui.qbutton_browse_bg_path.setHidden(False)
|
|
1581
|
-
self.bg_option = "Measured"
|
|
1582
|
-
elif state == 2:
|
|
1583
|
-
self.ui.label_bg_path.setHidden(True)
|
|
1584
|
-
self.ui.le_bg_path.setHidden(True)
|
|
1585
|
-
self.ui.qbutton_browse_bg_path.setHidden(True)
|
|
1586
|
-
self.bg_option = "Estimated"
|
|
1587
|
-
elif state == 3:
|
|
1588
|
-
self.ui.label_bg_path.setHidden(False)
|
|
1589
|
-
self.ui.le_bg_path.setHidden(False)
|
|
1590
|
-
self.ui.qbutton_browse_bg_path.setHidden(False)
|
|
1591
|
-
self.bg_option = "Measured + Estimated"
|
|
1592
|
-
|
|
1593
|
-
@Slot()
|
|
1594
|
-
def enter_gpu_id(self):
|
|
1595
|
-
self.gpu_id = int(self.ui.le_gpu_id.text())
|
|
1596
|
-
|
|
1597
|
-
@Slot()
|
|
1598
|
-
def enter_use_gpu(self):
|
|
1599
|
-
state = self.ui.chb_use_gpu.checkState().value
|
|
1600
|
-
if state == 2:
|
|
1601
|
-
self.use_gpu = True
|
|
1602
|
-
elif state == 0:
|
|
1603
|
-
self.use_gpu = False
|
|
1604
|
-
|
|
1605
|
-
@Slot()
|
|
1606
|
-
def enter_rotate_orientation(self):
|
|
1607
|
-
state = self.ui.cb_rotate_orientation.checkState().value
|
|
1608
|
-
if state == 2:
|
|
1609
|
-
self.rotate_orientation = True
|
|
1610
|
-
elif state == 0:
|
|
1611
|
-
self.rotate_orientation = False
|
|
1612
|
-
|
|
1613
|
-
@Slot()
|
|
1614
|
-
def enter_flip_orientation(self):
|
|
1615
|
-
state = self.ui.cb_flip_orientation.checkState().value
|
|
1616
|
-
if state == 2:
|
|
1617
|
-
self.flip_orientation = True
|
|
1618
|
-
elif state == 0:
|
|
1619
|
-
self.flip_orientation = False
|
|
1620
|
-
|
|
1621
|
-
@Slot()
|
|
1622
|
-
def enter_invert_phase_contrast(self):
|
|
1623
|
-
state = self.ui.cb_invert_phase_contrast.checkState().value
|
|
1624
|
-
if state == 2:
|
|
1625
|
-
self.invert_phase_contrast = True
|
|
1626
|
-
elif state == 0:
|
|
1627
|
-
self.invert_phase_contrast = False
|
|
1628
|
-
|
|
1629
|
-
@Slot()
|
|
1630
|
-
def enter_recon_wavelength(self):
|
|
1631
|
-
self.recon_wavelength = int(self.ui.le_recon_wavelength.text())
|
|
1632
|
-
|
|
1633
|
-
@Slot()
|
|
1634
|
-
def enter_obj_na(self):
|
|
1635
|
-
self.obj_na = float(self.ui.le_obj_na.text())
|
|
1636
|
-
|
|
1637
|
-
@Slot()
|
|
1638
|
-
def enter_cond_na(self):
|
|
1639
|
-
self.cond_na = float(self.ui.le_cond_na.text())
|
|
1640
|
-
|
|
1641
|
-
@Slot()
|
|
1642
|
-
def enter_mag(self):
|
|
1643
|
-
self.mag = float(self.ui.le_mag.text())
|
|
1644
|
-
|
|
1645
|
-
@Slot()
|
|
1646
|
-
def enter_ps(self):
|
|
1647
|
-
self.ps = float(self.ui.le_ps.text())
|
|
1648
|
-
|
|
1649
|
-
@Slot()
|
|
1650
|
-
def enter_n_media(self):
|
|
1651
|
-
self.n_media = float(self.ui.le_n_media.text())
|
|
1652
|
-
|
|
1653
|
-
@Slot()
|
|
1654
|
-
def enter_pad_z(self):
|
|
1655
|
-
self.pad_z = int(self.ui.le_pad_z.text())
|
|
1656
|
-
|
|
1657
1167
|
@Slot()
|
|
1658
1168
|
def enter_pause_updates(self):
|
|
1659
1169
|
"""
|
|
@@ -2007,85 +1517,9 @@ class MainWidget(QWidget):
|
|
|
2007
1517
|
self.ui.qbutton_stop_calib.clicked.connect(self.worker.quit)
|
|
2008
1518
|
self.worker.aborted.connect(self._handle_calib_abort)
|
|
2009
1519
|
|
|
2010
|
-
# Connect to BG Correction Path
|
|
2011
|
-
self.worker.bg_path_update_emitter.connect(self.handle_bg_path_update)
|
|
2012
|
-
|
|
2013
1520
|
# Start Capture Background Thread
|
|
2014
1521
|
self.worker.start()
|
|
2015
1522
|
|
|
2016
|
-
@Slot(bool)
|
|
2017
|
-
def acq_ret_ori(self):
|
|
2018
|
-
"""
|
|
2019
|
-
Wrapper function to acquire birefringence stack/image and plot in napari
|
|
2020
|
-
Returns
|
|
2021
|
-
-------
|
|
2022
|
-
|
|
2023
|
-
"""
|
|
2024
|
-
|
|
2025
|
-
self._check_requirements_for_acq("birefringence")
|
|
2026
|
-
|
|
2027
|
-
# Init Worker and thread
|
|
2028
|
-
self.worker = PolarizationAcquisitionWorker(
|
|
2029
|
-
self, self.calib, "birefringence"
|
|
2030
|
-
)
|
|
2031
|
-
|
|
2032
|
-
# Connect Handlers
|
|
2033
|
-
self.worker.bire_image_emitter.connect(self.handle_bire_image_update)
|
|
2034
|
-
self.worker.started.connect(self._disable_buttons)
|
|
2035
|
-
self.worker.finished.connect(self._enable_buttons)
|
|
2036
|
-
self.worker.errored.connect(self._handle_acq_error)
|
|
2037
|
-
|
|
2038
|
-
# Start Thread
|
|
2039
|
-
self.worker.start()
|
|
2040
|
-
|
|
2041
|
-
@Slot(bool)
|
|
2042
|
-
def acq_phase_from_bf(self):
|
|
2043
|
-
"""
|
|
2044
|
-
Wrapper function to acquire phase stack and plot in napari
|
|
2045
|
-
"""
|
|
2046
|
-
|
|
2047
|
-
self._check_requirements_for_acq("phase")
|
|
2048
|
-
|
|
2049
|
-
# Init worker and thread
|
|
2050
|
-
self.worker = BFAcquisitionWorker(self)
|
|
2051
|
-
|
|
2052
|
-
# Connect Handlers
|
|
2053
|
-
self.worker.phase_image_emitter.connect(self.handle_phase_image_update)
|
|
2054
|
-
self.worker.phase_reconstructor_emitter.connect(
|
|
2055
|
-
self.handle_qlipp_reconstructor_update
|
|
2056
|
-
)
|
|
2057
|
-
self.worker.started.connect(self._disable_buttons)
|
|
2058
|
-
self.worker.finished.connect(self._enable_buttons)
|
|
2059
|
-
self.worker.errored.connect(self._handle_acq_error)
|
|
2060
|
-
|
|
2061
|
-
# Start thread
|
|
2062
|
-
self.worker.start()
|
|
2063
|
-
|
|
2064
|
-
@Slot(bool)
|
|
2065
|
-
def acq_ret_ori_phase(self):
|
|
2066
|
-
"""
|
|
2067
|
-
Wrapper function to acquire both birefringence and phase stack and plot in napari
|
|
2068
|
-
"""
|
|
2069
|
-
|
|
2070
|
-
self._check_requirements_for_acq("phase")
|
|
2071
|
-
|
|
2072
|
-
# Init worker and thread
|
|
2073
|
-
self.worker = PolarizationAcquisitionWorker(self, self.calib, "all")
|
|
2074
|
-
|
|
2075
|
-
# connect handlers
|
|
2076
|
-
self.worker.phase_image_emitter.connect(self.handle_phase_image_update)
|
|
2077
|
-
self.worker.phase_reconstructor_emitter.connect(
|
|
2078
|
-
self.handle_qlipp_reconstructor_update
|
|
2079
|
-
)
|
|
2080
|
-
self.worker.bire_image_emitter.connect(self.handle_bire_image_update)
|
|
2081
|
-
self.worker.started.connect(self._disable_buttons)
|
|
2082
|
-
self.worker.finished.connect(self._enable_buttons)
|
|
2083
|
-
self.worker.errored.connect(self._handle_acq_error)
|
|
2084
|
-
self.ui.qbutton_stop_acq.clicked.connect(self.worker.quit)
|
|
2085
|
-
|
|
2086
|
-
# Start Thread
|
|
2087
|
-
self.worker.start()
|
|
2088
|
-
|
|
2089
1523
|
@Slot(bool)
|
|
2090
1524
|
def save_config(self):
|
|
2091
1525
|
path = self._open_file_dialog(self.save_config_path, "save")
|