def test_add_stream(self): test.gui_loop() mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) # stream_bar.setMicroscope(mic_mod, None) self.assertEqual(stream_bar.btn_add_stream.IsShown(), True) # No actions should be linked to the add stream button self.assertEqual(len(stream_bar.get_actions()), 0) # Add a callback/name combo to the add button def brightfield_callback(): fake_stream = FakeBrightfieldStream("Brightfield") fixed_entry = stream_comp.StreamPanel(stream_bar, fake_stream, mic_mod) stream_bar.add_stream(fixed_entry) stream_bar.add_action("Brightfield", brightfield_callback) brightfield_callback() test.gui_loop() self.assertEqual(len(stream_bar.get_actions()), 1) self.assertEqual(stream_bar.get_size(), 1) # Add another callback/name combo to the add button def sem_callback(): fake_stream = FakeSEMStream("SEM:EDT") fixed_entry = stream_comp.StreamPanel(stream_bar, fake_stream, mic_mod) stream_bar.add_stream(fixed_entry) stream_bar.add_action("SEM:EDT", sem_callback) sem_callback() test.gui_loop() self.assertEqual(len(stream_bar.get_actions()), 2) self.assertEqual(stream_bar.get_size(), 2) # Remove the Brightfield stream stream_bar.remove_action("Brightfield") test.gui_loop() self.assertEqual(len(stream_bar.get_actions()), 1) # Add another callback/name combo to the add button def custom_callback(): fake_stream = FakeFluoStream("Custom") custom_entry = stream_comp.StreamPanel(stream_bar, fake_stream, mic_mod) stream_bar.add_stream(custom_entry) stream_bar.add_action("Custom", custom_callback) # Clear remaining streams stream_bar.clear() test.gui_loop()
def test_bandwidth_stream_panel(self): mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) fake_spec_stream = FakeSpectrumStream("First Fixed Stream") stream_panel = stream_comp.StreamPanel(stream_bar, fake_spec_stream, mic_mod) stream_bar.add_stream(stream_panel) test.gui_loop()
def test_bandwidth_stream_panel(self): tab_mod = self.create_simple_tab_model() stream_bar = self.app.test_frame.stream_bar _ = StreamController(tab_mod, stream_bar) fake_spec_stream = FakeSpectrumStream("First Fixed Stream") stream_panel = stream_comp.StreamPanel(stream_bar, fake_spec_stream, tab_mod) stream_bar.add_stream(stream_panel) test.gui_loop()
def __init__(self, tab_panel, tab_data, highlight_change=False): super(SecomSettingsController, self).__init__(tab_data) main_data = tab_data.main self._sem_panel = SemSettingsController( tab_panel.fp_settings_secom_sem, "No SEM found", highlight_change, tab_data) self._optical_panel = OpticalSettingsController( tab_panel.fp_settings_secom_optical, "No optical microscope found", highlight_change, tab_data) # Add the components based on what is available # TODO: move it to a separate thread to save time at init? if main_data.ccd: # Hide exposureTime as it's in local settings of the stream self.add_hw_component(main_data.ccd, self._optical_panel, hidden={"exposureTime"}) if hasattr(tab_data, "confocal_set_stream"): conf_set_e = StreamController(tab_panel.pnl_opt_streams, tab_data.confocal_set_stream, tab_data) conf_set_e.stream_panel.flatten() # removes the expander header # StreamController looks pretty much the same as SettingController self.setting_controllers.append(conf_set_e) else: tab_panel.pnl_opt_streams.Hide() # Not needed # For now, we assume that the pinhole (axis) is global: valid for all # the confocal streams and FLIM stream. That's partly because most likely # the user wouldn't want to have separate values... and also because # anyway we don't currently support local stream axes. if main_data.pinhole: conf = get_hw_config(main_data.pinhole, self._hw_settings_config) for a in ("d", ): if a not in main_data.pinhole.axes: continue self._optical_panel.add_axis(a, main_data.pinhole, conf.get(a)) if main_data.ebeam: self.add_hw_component(main_data.ebeam, self._sem_panel) # If can do AutoContrast, display the button # TODO: check if detector has a .applyAutoContrast() method, instead # of detecting indirectly via the presence of .bpp. det = main_data.sed or main_data.bsd if det and model.hasVA(det, "bpp"): self._sem_panel.add_bc_control(det)
def test_zflatten(self): test.gui_loop() mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) fake_sem_stream = FakeSEMStream("Flatten Test") stream_panel = stream_comp.StreamPanel(stream_bar, fake_sem_stream, mic_mod) stream_bar.add_stream(stream_panel) test.gui_loop() stream_panel.flatten() test.gui_loop()
def test_zflatten(self): test.gui_loop() tab_mod = self.create_simple_tab_model() stream_bar = self.app.test_frame.stream_bar _ = StreamController(tab_mod, stream_bar) fake_sem_stream = FakeSEMStream("Flatten Test") stream_panel = stream_comp.StreamPanel(stream_bar, fake_sem_stream, tab_mod) stream_bar.add_stream(stream_panel) test.gui_loop() stream_panel.flatten() test.gui_loop()
def test_dyeexpander(self): tab_mod = self.create_simple_tab_model() stream_bar = self.app.test_frame.stream_bar _ = StreamController(tab_mod, stream_bar) fake_fluo_stream = FakeFluoStream("Fluo Stream") dye_panel = stream_comp.StreamPanel(stream_bar, fake_fluo_stream, tab_mod) stream_bar.add_stream(dye_panel) # print stream_panel._expander.GetSize() stream_panel = stream_comp.StreamPanel(stream_bar, fake_fluo_stream, tab_mod) stream_bar.add_stream(stream_panel) # print stream_panel._expander.GetSize() test.gui_loop()
def test_standardexpander(self): mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) fake_sem_stream = FakeSEMStream("First Fixed Stream") stream_panel = stream_comp.StreamPanel(stream_bar, fake_sem_stream, mic_mod) stream_bar.add_stream(stream_panel) test.gui_loop() self.assertEqual("First Fixed Stream", stream_panel._expander._label_ctrl.GetLabel()) test.gui_loop() # Clear remaining streams stream_bar.clear() test.gui_loop() self.assertEqual(stream_bar.get_size(), 0)
def test_dyeexpander(self): mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) fake_fluo_stream = FakeFluoStream("Fluo Stream") dye_panel = stream_comp.StreamPanel(stream_bar, fake_fluo_stream, mic_mod) stream_bar.add_stream(dye_panel) # print stream_panel._expander.GetSize() stream_panel = stream_comp.StreamPanel(stream_bar, fake_fluo_stream, mic_mod) stream_bar.add_stream(stream_panel) # print stream_panel._expander.GetSize() test.gui_loop() # Clear remaining streams stream_bar.clear() test.gui_loop() self.assertEqual(stream_bar.get_size(), 0)
def __init__(self, parent, orig_tab_data): xrcfr_acq.__init__(self, parent) self.conf = get_acqui_conf() for n in presets: self.cmb_presets.Append(n) # TODO: record and reuse the preset used? self.cmb_presets.Select(0) self.filename = model.StringVA(self._get_default_filename()) self.filename.subscribe(self._onFilename, init=True) # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None # duplicate the interface, but with only one view self._tab_data_model = self.duplicate_tab_data_model(orig_tab_data) # Create a new settings controller for the acquisition dialog self._settings_controller = SecomSettingsController(self, self._tab_data_model, highlight_change=True) # FIXME: pass the fold_panels # Compute the preset values for each preset self._preset_values = {} # dict string -> dict (SettingEntries -> value) orig_entries = self._settings_controller.entries self._orig_settings = preset_as_is(orig_entries) # to detect changes for n, preset in presets.items(): self._preset_values[n] = preset(orig_entries) # Presets which have been confirmed on the hardware self._presets_confirmed = set() # (string) orig_view = orig_tab_data.focussedView.value view = self._tab_data_model.focussedView.value self.stream_controller = StreamController(self._tab_data_model, self.pnl_secom_streams) # The streams currently displayed are the one visible self.add_all_streams(orig_view.getStreams()) # If it could be possible to do fine alignment, allow the user to choose if self._can_fine_align(self._tab_data_model.streams.value): self.chkbox_fine_align.Show() # Set to True to make it the default, but will be automatically # disabled later if the current visible streams don't allow it. self.chkbox_fine_align.Value = True main_data = self._tab_data_model.main self._ovrl_stream = stream.OverlayStream("fine alignment", main_data.ccd, main_data.ebeam, main_data.sed) self._ovrl_stream.dwellTime.value = main_data.fineAlignDwellTime.value else: self.chkbox_fine_align.Show(False) self.chkbox_fine_align.Value = False self._prev_fine_align = self.chkbox_fine_align.Value # make sure the view displays the same thing as the one we are # duplicating view.view_pos.value = orig_view.view_pos.value view.mpp.value = orig_view.mpp.value view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.setView(view, self._tab_data_model) self.Bind(wx.EVT_CHAR_HOOK, self.on_key) self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close) self.btn_change_file.Bind(wx.EVT_BUTTON, self.on_change_file) self.btn_secom_acquire.Bind(wx.EVT_BUTTON, self.on_acquire) self.cmb_presets.Bind(wx.EVT_COMBOBOX, self.on_preset) self.Bind(wx.EVT_CLOSE, self.on_close) # on_streams_changed is compatible because it doesn't use the args self.chkbox_fine_align.Bind(wx.EVT_CHECKBOX, self.on_streams_changed) self.on_preset(None) # will force setting the current preset pub.subscribe(self.on_setting_change, 'setting.changed') # TODO: we should actually listen to the stream tree, but it's not # currently possible. # Currently just use view.last_update which should be "similar" view.lastUpdate.subscribe(self.on_streams_changed)
class AcquisitionDialog(xrcfr_acq): """ Wrapper class responsible for additional initialization of the Acquisition Dialog created in XRCed """ # TODO: share more code with cont.acquisition def __init__(self, parent, orig_tab_data): xrcfr_acq.__init__(self, parent) self.conf = get_acqui_conf() for n in presets: self.cmb_presets.Append(n) # TODO: record and reuse the preset used? self.cmb_presets.Select(0) self.filename = model.StringVA(self._get_default_filename()) self.filename.subscribe(self._onFilename, init=True) # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None # duplicate the interface, but with only one view self._tab_data_model = self.duplicate_tab_data_model(orig_tab_data) # Create a new settings controller for the acquisition dialog self._settings_controller = SecomSettingsController(self, self._tab_data_model, highlight_change=True) # FIXME: pass the fold_panels # Compute the preset values for each preset self._preset_values = {} # dict string -> dict (SettingEntries -> value) orig_entries = self._settings_controller.entries self._orig_settings = preset_as_is(orig_entries) # to detect changes for n, preset in presets.items(): self._preset_values[n] = preset(orig_entries) # Presets which have been confirmed on the hardware self._presets_confirmed = set() # (string) orig_view = orig_tab_data.focussedView.value view = self._tab_data_model.focussedView.value self.stream_controller = StreamController(self._tab_data_model, self.pnl_secom_streams) # The streams currently displayed are the one visible self.add_all_streams(orig_view.getStreams()) # If it could be possible to do fine alignment, allow the user to choose if self._can_fine_align(self._tab_data_model.streams.value): self.chkbox_fine_align.Show() # Set to True to make it the default, but will be automatically # disabled later if the current visible streams don't allow it. self.chkbox_fine_align.Value = True main_data = self._tab_data_model.main self._ovrl_stream = stream.OverlayStream("fine alignment", main_data.ccd, main_data.ebeam, main_data.sed) self._ovrl_stream.dwellTime.value = main_data.fineAlignDwellTime.value else: self.chkbox_fine_align.Show(False) self.chkbox_fine_align.Value = False self._prev_fine_align = self.chkbox_fine_align.Value # make sure the view displays the same thing as the one we are # duplicating view.view_pos.value = orig_view.view_pos.value view.mpp.value = orig_view.mpp.value view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.setView(view, self._tab_data_model) self.Bind(wx.EVT_CHAR_HOOK, self.on_key) self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close) self.btn_change_file.Bind(wx.EVT_BUTTON, self.on_change_file) self.btn_secom_acquire.Bind(wx.EVT_BUTTON, self.on_acquire) self.cmb_presets.Bind(wx.EVT_COMBOBOX, self.on_preset) self.Bind(wx.EVT_CLOSE, self.on_close) # on_streams_changed is compatible because it doesn't use the args self.chkbox_fine_align.Bind(wx.EVT_CHECKBOX, self.on_streams_changed) self.on_preset(None) # will force setting the current preset pub.subscribe(self.on_setting_change, 'setting.changed') # TODO: we should actually listen to the stream tree, but it's not # currently possible. # Currently just use view.last_update which should be "similar" view.lastUpdate.subscribe(self.on_streams_changed) def duplicate_tab_data_model(self, orig): """ Duplicate a MicroscopyGUIData and adapt it for the acquisition window The streams will be shared, but not the views orig (MicroscopyGUIData) return (MicroscopyGUIData) """ new = copy.copy(orig) # shallow copy # create view (which cannot move or focus) view = guimodel.MicroscopeView(orig.focussedView.value.name.value) # differentiate it (only one view) new.views = {"all": view} new.focussedView = model.VigilantAttribute(view) new.viewLayout = model.IntEnumerated(guimodel.VIEW_LAYOUT_ONE, choices=set([guimodel.VIEW_LAYOUT_ONE])) return new def add_all_streams(self, visible_streams): """ Add all the streams present in the interface model to the stream panel. visible_streams (list of streams): the streams that should be visible """ # the order the streams are added should not matter on the display, so # it's ok to not duplicate the streamTree literally view = self._tab_data_model.focussedView.value # Add stream to view first, so that the "visible" button is correct for s in visible_streams: view.addStream(s) # go through all the streams available in the interface model for s in self._tab_data_model.streams.value: sp = self.stream_controller.addStreamForAcquisition(s) def remove_all_streams(self): """ Remove the streams we added to the view on creation """ # Ensure we don't update the view after the window is destroyed view = self._tab_data_model.focussedView.value for s in view.getStreams(): view.removeStream(s) def find_current_preset(self): """ find the name of the preset identical to the current settings (not including "Custom") returns (string): name of the preset raises KeyError: if no preset can be found """ # check each preset for n, settings in self._preset_values.items(): # compare each value between the current and proposed different = False for entry, value in settings.items(): if entry.va.value != value: different = True break if not different: return n raise KeyError() def _can_fine_align(self, streams): """ Return True if with the given streams it would make sense to fine align streams (iterable of Stream) return (bool): True if at least a SEM and an optical stream are present """ # check for a SEM stream for s in streams: if isinstance(s, EM_STREAMS): break else: return False # check for an optical stream for s in streams: if isinstance(s, OPTICAL_STREAMS): break else: return False return True @call_after def update_setting_display(self): # if gauge was left over from an error => now hide it if self.gauge_acq.IsShown(): self.gauge_acq.Hide() self.Layout() # Enable/disable Fine alignment check box streams = self._tab_data_model.focussedView.value.getStreams() can_fa = self._can_fine_align(streams) if self.chkbox_fine_align.Enabled: self._prev_fine_align = self.chkbox_fine_align.Value self.chkbox_fine_align.Enable(can_fa) # Uncheck if disabled, otherwise put same as previous value self.chkbox_fine_align.Value = (can_fa and self._prev_fine_align) self.update_acquisition_time() # update highlight for se, value in self._orig_settings.items(): se.highlight(se.va.value != value) def on_streams_changed(self, val): """ When the list of streams to acquire has changed """ self.update_setting_display() def on_setting_change(self, setting_ctrl): self.update_setting_display() # check presets and fall-back to custom try: preset_name = self.find_current_preset() logging.debug("Detected preset %s", preset_name) except KeyError: # should not happen with the current preset_no_change logging.exception("Couldn't match any preset") preset_name = u"Custom" self.cmb_presets.SetValue(preset_name) def update_acquisition_time(self): streams = self._tab_data_model.focussedView.value.getStreams() if streams: if self.chkbox_fine_align.Value: streams.add(self._ovrl_stream) acq_time = acq.estimateTime(streams) acq_time = math.ceil(acq_time) # round a bit pessimistically txt = "The estimated acquisition time is {}." txt = txt.format(units.readable_time(acq_time)) else: txt = "No streams present." self.lbl_acqestimate.SetLabel(txt) def _get_default_filename(self): """ Return a good default filename """ # TODO: check the file doesn't yet exist (if the computer clock is # correct it's unlikely) return os.path.join(self.conf.last_path, u"%s%s" % (time.strftime("%Y%m%d-%H%M%S"), self.conf.last_extension) ) def _onFilename(self, name): """ updates the GUI when the filename is updated """ # decompose into path/file path, base = os.path.split(name) self.txt_destination.SetValue(unicode(path)) # show the end of the path (usually more important) self.txt_destination.SetInsertionPointEnd() self.txt_filename.SetValue(unicode(base)) def on_preset(self, evt): preset_name = self.cmb_presets.GetValue() try: new_preset = self._preset_values[preset_name] except KeyError: logging.debug("Not changing settings for preset %s", preset_name) return logging.debug("Changing setting to preset %s", preset_name) # TODO: presets should also be able to change the special stream settings # (eg: accumulation/interpolation) when we have them # apply the recorded values apply_preset(new_preset) # The hardware might not exactly apply the setting as computed in the # preset. We need the _exact_ same value to find back which preset is # currently selected. So update the values the first time. # TODO: this should not be necessary once the settings only change the # stream settings, and not directly the hardware. if not preset_name in self._presets_confirmed: for se in new_preset.keys(): new_preset[se] = se.va.value self._presets_confirmed.add(preset_name) self.update_setting_display() def on_key(self, evt): """ Dialog key press handler. """ if evt.GetKeyCode() == wx.WXK_ESCAPE: self.Close() else: evt.Skip() def on_change_file(self, evt): """ Shows a dialog to change the path, name, and format of the acquisition file. returns nothing, but updates .filename and .conf """ new_name = ShowAcquisitionFileDialog(self, self.filename.value) self.filename.value = new_name def on_close(self, evt): """ Close event handler that executes various cleanup actions """ if self.acq_future: # TODO: ask for confirmation before cancelling? # What to do if the acquisition is done while asking for # confirmation? msg = "Cancelling acquisition due to closing the acquisition window" logging.info(msg) self.acq_future.cancel() self.remove_all_streams() # stop listening to events pub.unsubscribe(self.on_setting_change, 'setting.changed') self.Destroy() def _pause_settings(self): """ Pause the settings of the GUI and save the values for restoring them later """ self._settings_controller.pause() self._settings_controller.enable(False) def _resume_settings(self): self._settings_controller.resume() self._settings_controller.enable(True) def on_acquire(self, evt): """ Start the acquisition (really) """ self.btn_secom_acquire.Disable() # disable estimation time updates during acquisition view = self._tab_data_model.focussedView.value view.lastUpdate.unsubscribe(self.on_streams_changed) # TODO: freeze all the settings so that it's not possible to change anything self._pause_settings() self.gauge_acq.Show() self.Layout() # to put the gauge at the right place # start acquisition + connect events to callback streams = self._tab_data_model.focussedView.value.getStreams() # Add the overlay stream if the fine alignment check box is checked if self.chkbox_fine_align.Value: streams.add(self._ovrl_stream) # It should never be possible to reach here with no streams self.acq_future = acq.acquire(streams) self._acq_future_connector = ProgessiveFutureConnector(self.acq_future, self.gauge_acq, self.lbl_acqestimate) self.acq_future.add_done_callback(self.on_acquisition_done) self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel) def on_cancel(self, evt): """ Called during acquisition when pressing the cancel button """ if not self.acq_future: msg = "Tried to cancel acquisition while it was not started" logging.warning(msg) return self.acq_future.cancel() # all the rest will be handled by on_acquisition_done() @call_after def on_acquisition_done(self, future): """ Callback called when the acquisition is finished (either successfully or cancelled) """ # bind button back to direct closure self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close) self._resume_settings() # reenable estimation time updates view = self._tab_data_model.focussedView.value view.lastUpdate.subscribe(self.on_streams_changed) try: data = future.result(1) # timeout is just for safety except CancelledError: # put back to original state: # re-enable the acquire button self.btn_secom_acquire.Enable() # hide progress bar (+ put pack estimated time) self.update_acquisition_time() self.gauge_acq.Hide() self.Layout() return except Exception: # We cannot do much: just warn the user and pretend it was cancelled logging.exception("Acquisition failed") self.btn_secom_acquire.Enable() self.lbl_acqestimate.SetLabel("Acquisition failed.") # leave the gauge, to give a hint on what went wrong. return # save result to file self.lbl_acqestimate.SetLabel("Saving file...") try: thumb = acq.computeThumbnail( self._tab_data_model.focussedView.value.stream_tree, future) filename = self.filename.value exporter = dataio.get_exporter(self.conf.last_format) exporter.export(filename, data, thumb) logging.info("Acquisition saved as file '%s'.", filename) except Exception: logging.exception("Saving acquisition failed") self.btn_secom_acquire.Enable() self.lbl_acqestimate.SetLabel("Saving acquisition file failed.") return self.lbl_acqestimate.SetLabel("Acquisition completed.") # We don't allow to acquire anymore => change button name self.btn_cancel.SetLabel("Close")
def test_stream_interface(self): test.gui_loop() mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) # stream_bar.setMicroscope(mic_mod, None) # Hide the Stream add button self.assertEqual(stream_bar.btn_add_stream.IsShown(), True) stream_bar.hide_add_button() test.gui_loop() self.assertEqual(stream_bar.btn_add_stream.IsShown(), False) # Show Stream add button stream_bar.show_add_button() test.gui_loop() self.assertEqual(stream_bar.btn_add_stream.IsShown(), True) # Add an editable entry fake_cstream = FakeFluoStream("First Custom Stream") custom_entry = stream_comp.StreamPanel(stream_bar, fake_cstream, mic_mod) stream_bar.add_stream(custom_entry) test.gui_loop() self.assertEqual(stream_bar.get_size(), 1) self.assertEqual(stream_bar.stream_panels.index(custom_entry), 0) # Add a fixed stream fake_fstream1 = FakeSEMStream("First Fixed Stream") fixed_entry = stream_comp.StreamPanel(stream_bar, fake_fstream1, mic_mod) stream_bar.add_stream(fixed_entry) test.gui_loop() self.assertEqual(stream_bar.get_size(), 2) self.assertEqual(stream_bar.stream_panels.index(fixed_entry), 0) self.assertEqual(stream_bar.stream_panels.index(custom_entry), 1) # Add a fixed stream fake_fstream2 = FakeSEMStream("Second Fixed Stream") fixed_entry2 = stream_comp.StreamPanel(stream_bar, fake_fstream2, mic_mod) stream_bar.add_stream(fixed_entry2) test.gui_loop() self.assertEqual(stream_bar.get_size(), 3) self.assertEqual(stream_bar.stream_panels.index(fixed_entry2), 1) self.assertEqual(stream_bar.stream_panels.index(custom_entry), 2) # Hide first stream by changing to a view that only show SEM streams semview = guimodel.MicroscopeView( "SEM view", stream_classes=(stream_mod.SEMStream, )) # stream_bar.hide_stream(0) mic_mod.focussedView.value = semview test.gui_loop() self.assertEqual(stream_bar.get_size(), 3) self.assertFalse(custom_entry.IsShown()) # Delete the second fixed stream stream_bar.remove_stream_panel(fixed_entry2) test.gui_loop() self.assertEqual(stream_bar.get_size(), 2) # Clear remainging streams stream_bar.clear() test.gui_loop() self.assertEqual(stream_bar.get_size(), 0)
def test_expander(self): test.gui_loop() mic_mod = FakeMicroscopeModel() stream_bar = self.app.test_frame.stream_bar _ = StreamController(mic_mod, stream_bar) fake_sem_stream = FakeSEMStream("First Fixed Stream") stream_panel = stream_comp.StreamPanel(stream_bar, fake_sem_stream, mic_mod) stream_bar.add_stream(stream_panel) test.gui_loop() # REMOVE BUTTON TEST old_label_pos = stream_panel._expander._label_ctrl.GetPosition() stream_panel.show_remove_btn(False) test.gui_loop() self.assertFalse(stream_panel._expander._btn_rem.IsShown()) new_label_pos = stream_panel._expander._label_ctrl.GetPosition() self.assertEqual(old_label_pos, new_label_pos) stream_panel.show_remove_btn(True) test.gui_loop() self.assertTrue(stream_panel._expander._btn_rem.IsShown()) new_label_pos = stream_panel._expander._label_ctrl.GetPosition() self.assertEqual(old_label_pos, new_label_pos) # END REMOVE BUTTON TEST # VISIBILITY BUTTON TEST old_pbtn_pos = stream_panel._expander._btn_updated.GetPosition() stream_panel.show_visible_btn(False) test.gui_loop() self.assertFalse(stream_panel._expander._btn_vis.IsShown()) new_pbtn_pos = stream_panel._expander._btn_updated.GetPosition() self.assertEqual(old_pbtn_pos, new_pbtn_pos) stream_panel.show_visible_btn(True) test.gui_loop() self.assertTrue(stream_panel._expander._btn_vis.IsShown()) new_pbtn_pos = stream_panel._expander._btn_updated.GetPosition() self.assertEqual(old_pbtn_pos, new_pbtn_pos) # END VISIBILITY BUTTON TEST # PLAY BUTTON TEST old_vbtn_pos = stream_panel._expander._btn_vis.GetPosition() stream_panel.show_updated_btn(False) test.gui_loop() self.assertFalse(stream_panel._expander._btn_updated.IsShown()) new_vbtn_pos = stream_panel._expander._btn_vis.GetPosition() self.assertEqual(old_vbtn_pos, new_vbtn_pos) stream_panel.show_updated_btn(True) test.gui_loop() self.assertTrue(stream_panel._expander._btn_updated.IsShown()) new_vbtn_pos = stream_panel._expander._btn_vis.GetPosition() self.assertEqual(old_vbtn_pos, new_vbtn_pos) # END BUTTON TEST # Clear remainging streams stream_bar.clear() test.gui_loop() self.assertEqual(stream_bar.get_size(), 0)
def test_static_streams(self): tab_mod = self.create_simple_tab_model() stream_bar = self.app.test_frame.stream_bar stream_cont = StreamController(tab_mod, stream_bar) fluomd = { model.MD_DESCRIPTION: "test", model.MD_ACQ_DATE: time.time(), model.MD_BPP: 12, model.MD_BINNING: (1, 2), # px, px model.MD_PIXEL_SIZE: (1e-6, 2e-5), # m/px model.MD_POS: (13.7e-3, -30e-3), # m model.MD_EXP_TIME: 1.2, # s model.MD_IN_WL: (500e-9, 520e-9), # m model.MD_OUT_WL: (600e-9, 630e-9), # m } fluod = model.DataArray(numpy.zeros((512, 256), dtype="uint16"), fluomd) # Create the streams the same way as when opening a file, in # cont.tabs.AnalysisTab.display_new_data() fluo_panel = stream_cont.addStatic("Fluo Stream", fluod, cls=stream_mod.StaticFluoStream, add_to_all_views=True) # Check it indeed created a panel entry to a static fluo stream self.assertIsInstance(fluo_panel.stream, stream_mod.StaticFluoStream) # White box testing: we expect that the excitation/emission information # are simple text, and no combo boxes (as it's all static) self.assertIsInstance(fluo_panel._txt_emission, wx.TextCtrl) self.assertIsInstance(fluo_panel._txt_excitation, wx.TextCtrl) test.gui_loop() semmd = { model.MD_DESCRIPTION: "test", model.MD_ACQ_DATE: time.time(), model.MD_BPP: 12, model.MD_BINNING: (1, 2), # px, px model.MD_PIXEL_SIZE: (1e-6, 2e-5), # m/px model.MD_POS: (13.7e-3, -30e-3), # m model.MD_EXP_TIME: 1.2, # s } semd = model.DataArray(numpy.zeros((256, 256), dtype="uint16"), semmd) # Create the streams the same way as when opening a file, in # cont.tabs.AnalysisTab.display_new_data() sem_panel = stream_cont.addStatic("SEM Stream", semd, cls=stream_mod.StaticSEMStream, add_to_all_views=True) # Check it indeed created a panel entry to a static fluo stream self.assertIsInstance(sem_panel.stream, stream_mod.StaticSEMStream) # White box testing: we expect autobc is available self.assertIsInstance(sem_panel._btn_autobc, wx.Control) # Clear remaining streams stream_bar.clear() test.gui_loop() self.assertEqual(stream_bar.get_size(), 0)