def open_acquisition_dialog(self): main_data = self._tab_data_model.main secom_live_tab = main_data.getTabByName("secom_live") # Indicate we are acquiring, especially important for the SEM which # need to get the external signal to not scan (cf MicroscopeController) main_data.is_acquiring.value = True # save the original settings settingsbar_controller = secom_live_tab.settingsbar_controller orig_entries = get_global_settings_entries(settingsbar_controller) for sc in secom_live_tab.streambar_controller.stream_controllers: orig_entries += get_local_settings_entries(sc) orig_settings = preset_as_is(orig_entries) settingsbar_controller.pause() settingsbar_controller.enable(False) # pause all the live acquisitions streambar_controller = secom_live_tab.streambar_controller streambar_controller.pauseStreams() streambar_controller.pause() if self._tab_data_model.tool.value == TOOL_SPOT: self._tab_data_model.tool.value = TOOL_NONE streambar_controller.enable(False) # create the dialog try: acq_dialog = AcquisitionDialog(self._tab_panel.Parent, self._tab_data_model) parent_size = [v * 0.77 for v in self._tab_panel.Parent.GetSize()] acq_dialog.SetSize(parent_size) acq_dialog.Center() action = acq_dialog.ShowModal() except Exception: logging.exception("Failed to create acquisition dialog") raise finally: acqmng.apply_preset(orig_settings) settingsbar_controller.enable(True) settingsbar_controller.resume() streambar_controller.enable(True) streambar_controller.resume() main_data.is_acquiring.value = False acq_dialog.Destroy() if action == wx.ID_OPEN: tab = main_data.getTabByName('analysis') main_data.tab.value = tab tab.load_data(acq_dialog.last_saved_file)
def open_acquisition_dialog(self): secom_live_tab = self._tab_data_model.main.getTabByName("secom_live") # Indicate we are acquiring, especially important for the SEM which # need to get the external signal to not scan (cf MicroscopeController) self._tab_data_model.main.is_acquiring.value = True # save the original settings settingsbar_controller = secom_live_tab.settingsbar_controller orig_entries = get_global_settings_entries(settingsbar_controller) for sc in secom_live_tab.streambar_controller.stream_controllers: orig_entries += get_local_settings_entries(sc) orig_settings = preset_as_is(orig_entries) settingsbar_controller.pause() settingsbar_controller.enable(False) # pause all the live acquisitions streambar_controller = secom_live_tab.streambar_controller paused_streams = streambar_controller.pauseStreams() streambar_controller.pause() streambar_controller.enable(False) # create the dialog try: acq_dialog = AcquisitionDialog(self._tab_panel.Parent, self._tab_data_model) parent_size = [v * 0.77 for v in self._tab_panel.Parent.GetSize()] acq_dialog.SetSize(parent_size) acq_dialog.Center() action = acq_dialog.ShowModal() finally: streambar_controller.resumeStreams(paused_streams) acqmng.apply_preset(orig_settings) settingsbar_controller.enable(True) settingsbar_controller.resume() streambar_controller.enable(True) streambar_controller.resume() self._tab_data_model.main.is_acquiring.value = False if action == wx.ID_OPEN: wx.GetApp().tab_controller.open_tab('analysis') self._tab_data_model.main.tab.value.load_data(acq_dialog.last_saved_file)
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(create_filename(self.conf.last_path, self.conf.fn_ptn, self.conf.last_extension, self.conf.fn_count)) self.filename.subscribe(self._onFilename, init=True) # The name of the last file that got written to disk (used for auto viewing on close) self.last_saved_file = None # True when acquisition occurs self.acquiring = False # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None self._main_data_model = orig_tab_data.main # 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 # also adds a "Reset" context menu ) orig_view = orig_tab_data.focussedView.value self._view = self._tab_data_model.focussedView.value self._hidden_view = StreamView("Plugin View Hidden") self.streambar_controller = StreamBarController(self._tab_data_model, self.pnl_secom_streams, static=True, ignore_view=True) # The streams currently displayed are the one visible self.add_all_streams() # The list of streams ready for acquisition (just used as a cache) self._acq_streams = {} # FIXME: pass the fold_panels # Compute the preset values for each preset self._preset_values = {} # dict string -> dict (SettingEntries -> value) self._orig_entries = get_global_settings_entries(self._settings_controller) for sc in self.streambar_controller.stream_controllers: self._orig_entries += get_local_settings_entries(sc) self._orig_settings = preset_as_is(self._orig_entries) # to detect changes for n, preset in presets.items(): self._preset_values[n] = preset(self._orig_entries) # Presets which have been confirmed on the hardware self._presets_confirmed = set() # (string) self.start_listening_to_va() # 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 for s in self._tab_data_model.streams.value: if isinstance(s, EMStream): em_det = s.detector em_emt = s.emitter elif isinstance(s, OpticalStream) and not isinstance(s, ScannedFluoStream): opt_det = s.detector self._ovrl_stream = stream.OverlayStream("Fine alignment", opt_det, em_emt, em_det, opm=self._main_data_model.opm) self._ovrl_stream.dwellTime.value = self._main_data_model.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 self._view.view_pos.value = orig_view.view_pos.value self._view.mpp.value = orig_view.mpp.value self._view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.canvas.fit_view_to_next_image = False self.pnl_view_acq.setView(self._view, self._tab_data_model) # The TOOL_ROA is not present because we don't allow the user to change # the ROA), so we need to explicitly request the canvas to show the ROA. if hasattr(self._tab_data_model, "roa") and self._tab_data_model.roa is not None: cnvs = self.pnl_view_acq.canvas self.roa_overlay = RepetitionSelectOverlay(cnvs, self._tab_data_model.roa, self._tab_data_model.fovComp) cnvs.add_world_overlay(self.roa_overlay) 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 # To update the estimated time when streams are removed/added self._view.stream_tree.flat.subscribe(self.on_streams_changed) self._hidden_view.stream_tree.flat.subscribe(self.on_streams_changed)
def __init__(self, parent, orig_tab_data): xrcfr_overview_acq.__init__(self, parent) self.conf = get_acqui_conf() # True when acquisition occurs self.acquiring = False self.data = None # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None self._main_data_model = orig_tab_data.main # duplicate the interface, but with only one view self._tab_data_model = self.duplicate_tab_data_model(orig_tab_data) # The pattern to use for storing each tile file individually # None disables storing them self.filename_tiles = create_filename(self.conf.last_path, "{datelng}-{timelng}-overview", ".ome.tiff") # Create a new settings controller for the acquisition dialog self._settings_controller = LocalizationSettingsController( self, self._tab_data_model, highlight_change=True # also adds a "Reset" context menu ) self.zsteps = model.IntContinuous(1, range=(1, 51)) self._zsteps_vac = VigilantAttributeConnector(self.zsteps, self.zstack_steps, events=wx.EVT_SLIDER) orig_view = orig_tab_data.focussedView.value self._view = self._tab_data_model.focussedView.value self.streambar_controller = StreamBarController(self._tab_data_model, self.pnl_secom_streams, static=True, ignore_view=True) # The streams currently displayed are the one visible self.add_streams() # The list of streams ready for acquisition (just used as a cache) self._acq_streams = {} # Compute the preset values for each preset self._orig_entries = get_global_settings_entries(self._settings_controller) self._orig_settings = preset_as_is(self._orig_entries) for sc in self.streambar_controller.stream_controllers: self._orig_entries += get_local_settings_entries(sc) self.start_listening_to_va() # make sure the view displays the same thing as the one we are # duplicating self._view.view_pos.value = orig_view.view_pos.value self._view.mpp.value = orig_view.mpp.value self._view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.canvas.fit_view_to_next_image = False self.pnl_view_acq.setView(self._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_secom_acquire.Bind(wx.EVT_BUTTON, self.on_acquire) self.Bind(wx.EVT_CLOSE, self.on_close) # on_streams_changed is compatible because it doesn't use the args # To update the estimated time when streams are removed/added self._view.stream_tree.flat.subscribe(self.on_streams_changed) # Set parameters for tiled acq self.overlap = 0.2 try: # Use the stage range, which can be overridden by the MD_POS_ACTIVE_RANGE, # which can be overridden by MD_OVERVIEW_RANGE. # Note: this last one might be temporary, until we have a RoA tool provided in the GUI. stage_rng = { "x": self._main_data_model.stage.axes["x"].range, "y": self._main_data_model.stage.axes["y"].range } stage_md = self._main_data_model.stage.getMetadata() if model.MD_POS_ACTIVE_RANGE in stage_md: stage_rng.update(stage_md[model.MD_POS_ACTIVE_RANGE]) if model.MD_OVERVIEW_RANGE in stage_md: stage_rng.update(stage_md[model.MD_OVERVIEW_RANGE]) # left, bottom, right, top self.area = (stage_rng["x"][0], stage_rng["y"][0], stage_rng["x"][1], stage_rng["y"][1]) except (KeyError, IndexError): raise ValueError("Failed to find stage.MD_POS_ACTIVE_RANGE with x and y range") # Note: It should never be possible to reach here with no streams streams = self.get_acq_streams() for s in streams: self._view.addStream(s) self.update_acquisition_time()
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) # The name of the last file that got written to disk (used for auto viewing on close) self.last_saved_file = None # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None self._main_data_model = orig_tab_data.main # 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 # also adds a "Reset" context menu ) # To turn on/off the fan self._orig_fan_speed = None orig_view = orig_tab_data.focussedView.value self._view = self._tab_data_model.focussedView.value self.streambar_controller = StreamBarController(self._tab_data_model, self.pnl_secom_streams) # The streams currently displayed are the one visible self.add_all_streams() # FIXME: pass the fold_panels # Compute the preset values for each preset self._preset_values = {} # dict string -> dict (SettingEntries -> value) orig_entries = get_global_settings_entries(self._settings_controller) for sc in self.streambar_controller.stream_controllers: orig_entries += get_local_settings_entries(sc) 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) # 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 for s in self._tab_data_model.streams.value: if isinstance(s, EMStream): em_det = s.detector em_emt = s.emitter elif isinstance(s, OpticalStream): opt_det = s.detector self._ovrl_stream = stream.OverlayStream("Fine alignment", opt_det, em_emt, em_det) if self._main_data_model.role == "delphi": self._main_data_model.fineAlignDwellTime.value = 0.5 self._ovrl_stream.dwellTime.value = self._main_data_model.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 self._view.view_pos.value = orig_view.view_pos.value self._view.mpp.value = orig_view.mpp.value self._view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.canvas.fit_view_to_next_image = False self.pnl_view_acq.setView(self._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 # TODO: use the presets VAs and subscribe to each of them, instead of # using pub/sub messages pub.subscribe(self.on_setting_change, 'setting.changed') # TODO: we should actually listen to the stream tree, but it's not # currently possible. => listen to .flat once it's there # Currently just use view.lastUpdate which should be "similar" # (but doesn't work if the stream contains no image) self._view.lastUpdate.subscribe(self.on_streams_changed)
def __init__(self, parent, orig_tab_data): xrcfr_overview_acq.__init__(self, parent) self.conf = get_acqui_conf() # True when acquisition occurs self.acquiring = False self.data = None # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None self._main_data_model = orig_tab_data.main # duplicate the interface, but with only one view self._tab_data_model = self.duplicate_tab_data_model(orig_tab_data) # Store the final image as {datelng}-{timelng}-overview # The pattern to store them in a sub folder, with the name xxxx-overview-tiles/xxx-overview-NxM.ome.tiff # The pattern to use for storing each tile file individually # None disables storing them save_dir = self.conf.last_path if isinstance(orig_tab_data, guimodel.CryoGUIData): save_dir = self.conf.pj_last_path self.filename = create_filename(save_dir, "{datelng}-{timelng}-overview", ".ome.tiff") assert self.filename.endswith(".ome.tiff") dirname, basename = os.path.split(self.filename) tiles_dir = os.path.join(dirname, basename[:-len(".ome.tiff")] + "-tiles") self.filename_tiles = os.path.join(tiles_dir, basename) # Create a new settings controller for the acquisition dialog self._settings_controller = LocalizationSettingsController( self, self._tab_data_model, ) self.zsteps = model.IntContinuous(1, range=(1, 51)) # The depth of field is an indication of how far the focus needs to move # to see the current in-focus position out-of-focus. So it's a good default # value for the zstep size. We use 2x to "really" see something else. # Typically, it's about 1 µm. dof = self._main_data_model.ccd.depthOfField.value self.zstep_size = model.FloatContinuous(2 * dof, range=(1e-9, 100e-6), unit="m") self._zstep_size_vac = VigilantAttributeConnector( self.zstep_size, self.zstep_size_ctrl, events=wx.EVT_COMMAND_ENTER) self.tiles_nx = model.IntContinuous(5, range=(1, 1000)) self.tiles_ny = model.IntContinuous(5, range=(1, 1000)) self._zsteps_vac = VigilantAttributeConnector(self.zsteps, self.zstack_steps, events=wx.EVT_SLIDER) self._tiles_n_vacx = VigilantAttributeConnector( self.tiles_nx, self.tiles_number_x, events=wx.EVT_COMMAND_ENTER) self._tiles_n_vacy = VigilantAttributeConnector( self.tiles_ny, self.tiles_number_y, events=wx.EVT_COMMAND_ENTER) self.area = None # None or 4 floats: left, top, right, bottom positions of the acquisition area (in m) orig_view = orig_tab_data.focussedView.value self._view = self._tab_data_model.focussedView.value self.streambar_controller = StreamBarController(self._tab_data_model, self.pnl_secom_streams, static=True, ignore_view=True) # The streams currently displayed are the one visible self.add_streams() # The list of streams ready for acquisition (just used as a cache) self._acq_streams = {} # Find every setting, and listen to it self._orig_entries = get_global_settings_entries( self._settings_controller) for sc in self.streambar_controller.stream_controllers: self._orig_entries += get_local_settings_entries(sc) self.start_listening_to_va() # make sure the view displays the same thing as the one we are # duplicating self._view.view_pos.value = orig_view.view_pos.value self._view.mpp.value = orig_view.mpp.value self._view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.canvas.fit_view_to_next_image = False self.pnl_view_acq.setView(self._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_secom_acquire.Bind(wx.EVT_BUTTON, self.on_acquire) self.Bind(wx.EVT_CLOSE, self.on_close) # Set parameters for tiled acq self.overlap = 0.2 try: # Use the stage range, which can be overridden by the MD_POS_ACTIVE_RANGE. # Note: this last one might be temporary, until we have a RoA tool provided in the GUI. self._tiling_rng = { "x": self._main_data_model.stage.axes["x"].range, "y": self._main_data_model.stage.axes["y"].range } stage_md = self._main_data_model.stage.getMetadata() if model.MD_POS_ACTIVE_RANGE in stage_md: self._tiling_rng.update(stage_md[model.MD_POS_ACTIVE_RANGE]) except (KeyError, IndexError): raise ValueError( "Failed to find stage.MD_POS_ACTIVE_RANGE with x and y range") # Note: It should never be possible to reach here with no streams streams = self.get_acq_streams() for s in streams: self._view.addStream(s) # To update the estimated time & area when streams are removed/added self._view.stream_tree.flat.subscribe(self.on_streams_changed, init=True)
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) # The name of the last file that got written to disk (used for auto viewing on close) self.last_saved_file = None # a ProgressiveFuture if the acquisition is going on self.acq_future = None self._acq_future_connector = None self._main_data_model = orig_tab_data.main # 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 # also adds a "Reset" context menu ) # To turn on/off the fan self._orig_fan_speed = None self._orig_fan_temp = None orig_view = orig_tab_data.focussedView.value self._view = self._tab_data_model.focussedView.value self.streambar_controller = StreamBarController( self._tab_data_model, self.pnl_secom_streams) # The streams currently displayed are the one visible self.add_all_streams() # FIXME: pass the fold_panels # Compute the preset values for each preset self._preset_values = { } # dict string -> dict (SettingEntries -> value) orig_entries = get_global_settings_entries(self._settings_controller) for sc in self.streambar_controller.stream_controllers: orig_entries += get_local_settings_entries(sc) 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) # 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 for s in self._tab_data_model.streams.value: if isinstance(s, EMStream): em_det = s.detector em_emt = s.emitter elif isinstance(s, OpticalStream): opt_det = s.detector self._ovrl_stream = stream.OverlayStream("Fine alignment", opt_det, em_emt, em_det) self._ovrl_stream.dwellTime.value = self._main_data_model.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 self._view.view_pos.value = orig_view.view_pos.value self._view.mpp.value = orig_view.mpp.value self._view.merge_ratio.value = orig_view.merge_ratio.value # attach the view to the viewport self.pnl_view_acq.canvas.fit_view_to_next_image = False self.pnl_view_acq.setView(self._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 # TODO: use the presets VAs and subscribe to each of them, instead of # using pub/sub messages pub.subscribe(self.on_setting_change, 'setting.changed') # TODO: we should actually listen to the stream tree, but it's not # currently possible. => listen to .flat once it's there # Currently just use view.lastUpdate which should be "similar" # (but doesn't work if the stream contains no image) self._view.lastUpdate.subscribe(self.on_streams_changed)