예제 #1
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        Similar to win.acquisition.on_acquire()
        """
        # Time-resolved data cannot be saved in .ome.tiff format for now
        # OME-TIFF wants to save each time data on a separate "page", which causes too many pages.
        has_temporal = False
        for s in self._tab_data_model.streams.value:
            if (isinstance(s, ScannedTemporalSettingsStream)
                    or isinstance(s, ScannedTCSettingsStream)
                    or isinstance(s, TemporalSpectrumSettingsStream)):
                has_temporal = True

        if (self.conf.last_format == 'TIFF' or self.conf.last_format
                == 'Serialized TIFF') and has_temporal:
            raise NotImplementedError("Cannot save temporal data in %s format, data format must be HDF5." \
                                      % self.conf.last_format)

        self._pause_streams()

        self.btn_acquire.Disable()
        self.btn_cancel.Enable()
        self._main_data_model.is_acquiring.value = True

        self.gauge_acq.Show()
        self.btn_cancel.Show()
        self._show_status_icons(None)
        self._tab_panel.Layout()  # to put the gauge at the right place

        # start acquisition + connect events to callback
        self.acq_future = acq.acquire(self._tab_data_model.acquisitionStreams)
        self._acq_future_connector = ProgressiveFutureConnector(
            self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)
예제 #2
0
    def showProgress(self, future):
        """
        Shows a progress bar, based on the status of the progressive future given.
        As long as the future is not finished, the buttons are disabled.

        future (None or Future): The progressive future to show the progress with
          the progress bar. If future is None, it will hide the progress bar.
          If future is cancellable, show a cancel button next to the progress bar.

        """

        if future is not None and not future.cancelled():
            self.current_future = future
            self.enable_buttons(False)

        self.Layout()
        self.Update()

        if self.current_future is None:
            self._acq_future_connector = None
            return
        else:
            if hasattr(self.current_future, "add_update_callback"):
                self._acq_future_connector = ProgressiveFutureConnector(
                    self.current_future, self.gauge_progress, self.lbl_gauge)
            else:
                # TODO: just pulse the gauge at a "good" frequency (need to use a timer)
                self.gauge_progress.Pulse()

            if hasattr(self.current_future, 'task_canceller'):
                self.btn_cancel.Enable()
            else:
                self.btn_cancel.Disable()

        future.add_done_callback(self._on_future_done)
예제 #3
0
    def _on_fine_align(self, event):
        """
        Called when the "Fine alignment" button is clicked
        """
        self._pause()
        main_data = self._main_data_model
        main_data.is_acquiring.value = True

        logging.debug("Starting overlay procedure")
        f = align.FindOverlay(self.OVRL_REPETITION,
                              main_data.fineAlignDwellTime.value,
                              self.OVRL_MAX_DIFF,
                              main_data.ebeam,
                              main_data.ccd,
                              main_data.sed,
                              skew=True)
        logging.debug("Overlay procedure is running...")
        self._acq_future = f
        # Transform Fine alignment button into cancel
        self._tab_panel.btn_fine_align.Bind(wx.EVT_BUTTON, self._on_cancel)
        self._tab_panel.btn_fine_align.Label = "Cancel"

        # Set up progress bar
        self._tab_panel.lbl_fine_align.Hide()
        self._tab_panel.gauge_fine_align.Show()
        self._sizer.Layout()
        self._faf_connector = ProgressiveFutureConnector(
            f, self._tab_panel.gauge_fine_align)

        f.add_done_callback(self._on_fa_done)
예제 #4
0
    def on_calibrate(self, evt):
        """
        Start or cancel the calibrations for all set regions of calibrations (ROC) when the calibration
        button is triggered. A progressive future for all rocs is created.
        :param evt: (GenButtonEvent) Button triggered.
        """
        # check if cancelled
        if self._tab_data.is_calibrating.value:
            logging.debug("Calibration was cancelled.")
            align_fastem._executor.cancel()  # all the rest will be handled by on_alignment_done()
            # FIXME cancelling does not yet display the correct label in the gui
            return

        # calibrate
        self._tab_data.is_calibrating.unsubscribe(self._on_is_acquiring)
        # Briefly unsubscribe as don't need to know about this event (is_acquiring = True):
        # It  would disable the calibration button, but want to be able to still cancel calibration.
        self._tab_data.is_calibrating.value = True  # make sure the acquire/tab buttons are disabled
        self._tab_data.is_calibrating.subscribe(self._on_is_acquiring)

        self._on_calibration_state()  # update the controls in the panel

        futures = {}
        try:
            for roc_num in sorted(self.calibration_regions.value.keys()):
                # check if calibration region (ROC) on scintillator is set (undefined = not set)
                roc = self.calibration_regions.value[roc_num]
                if roc.coordinates.value != stream.UNDEFINED_ROI:

                    # calculate the center position of the ROC (half field right/bottom
                    # compared to top/left corner in view)
                    xmin, ymin, _, _ = roc.coordinates.value
                    field_size = (self._tab_data.main.multibeam.resolution.value[0]
                                  * self._tab_data.main.multibeam.pixelSize.value[0],
                                  self._tab_data.main.multibeam.resolution.value[1]
                                  * self._tab_data.main.multibeam.pixelSize.value[1])
                    roc_center = (xmin + field_size[0] / 2, ymin + field_size[1] / 2)

                    # start calibration
                    f = align.fastem.align(self._main_data_model.ebeam, self._main_data_model.multibeam,
                                           self._main_data_model.descanner, self._main_data_model.mppc,
                                           self._main_data_model.stage, self._main_data_model.ccd,
                                           self._main_data_model.beamshift, self._main_data_model.det_rotator,
                                           calibrations=self.calibrations, stage_pos=roc_center)
                    t = align.fastem.estimate_calibration_time(self.calibrations)
                    # also handles cancelling and exceptions
                    f.add_done_callback(partial(self._on_calibration_done, roc_num=roc_num))
                    futures[f] = t

            calib_future = model.ProgressiveBatchFuture(futures)
            # also handles cancelling and exceptions
            calib_future.add_done_callback(self._on_batch_calibrations_done)
            # connect the future to the progress bar and its label
            self._future_connector = ProgressiveFutureConnector(calib_future, self.gauge, self.label, full=False)
        except Exception as ex:  # In case all calibrations failed to start
            logging.warning("Calibration failed with %s", ex)
            for f in futures.keys():
                f.cancel()  # cancel all sub-futures
            self._main_data_model.is_acquiring.value = False
            self._update_calibration_controls("Calibrations failed.")
예제 #5
0
    def _on_auto_center(self, event):
        """
        Called when the "Auto centering" button is clicked
        """
        # Force spot mode: not needed by the code, but makes sense for the user
        self._tab_data_model.tool.value = guimod.TOOL_SPOT
        self._pause()

        main_data = self._main_data_model
        main_data.is_acquiring.value = True

        logging.debug("Starting auto centering procedure")
        f = align.AlignSpot(main_data.ccd,
                            self._aligner_xy,
                            main_data.ebeam,
                            main_data.focus,
                            type=OBJECTIVE_MOVE)
        logging.debug("Auto centering is running...")
        self._acq_future = f
        # Transform auto centering button into cancel
        self._tab_panel.btn_auto_center.Bind(wx.EVT_BUTTON, self._on_cancel)
        self._tab_panel.btn_auto_center.Label = "Cancel"

        # Set up progress bar
        self._tab_panel.lbl_auto_center.Hide()
        self._tab_panel.gauge_auto_center.Show()
        self._sizer.Layout()
        self._acf_connector = ProgressiveFutureConnector(
            f, self._tab_panel.gauge_auto_center)

        f.add_done_callback(self._on_ac_done)
예제 #6
0
    def on_calibrate(self, evt):
        """
        Start or cancel the calibration when the button is triggered.
        :param evt: (GenButtonEvent) Button triggered.
        """
        # check if cancelled
        if self._tab_data.is_calibrating.value:
            logging.debug("Calibration was cancelled.")
            align_fastem._executor.cancel()  # all the rest will be handled by on_alignment_done()
            return

        # calibrate
        self._tab_data.is_calibrating.unsubscribe(self._on_is_acquiring)
        # Don't catch this event (is_calibrating = True) - this would disable the button,
        # but it should be still enabled in order to be able to cancel the calibration
        self._tab_data.is_calibrating.value = True  # make sure the acquire/tab buttons are disabled
        self._tab_data.is_calibrating.subscribe(self._on_is_acquiring)

        self._on_calibration_state()  # update the controls in the panel

        # Start alignment
        f = align.fastem.align(self._main_data_model.ebeam, self._main_data_model.multibeam,
                               self._main_data_model.descanner, self._main_data_model.mppc,
                               self._main_data_model.stage, self._main_data_model.ccd,
                               self._main_data_model.beamshift, self._main_data_model.det_rotator,
                               calibrations=self.calibrations)

        f.add_done_callback(self._on_calibration_done)  # also handles cancelling and exceptions
        # connect the future to the progress bar and its label
        self._future_connector = ProgressiveFutureConnector(f, self.gauge, self.label, full=False)
예제 #7
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        """
        self._main_data_model.is_acquiring.value = True
        self.btn_acquire.Enable(False)
        self.btn_cancel.Enable(True)
        self.btn_cancel.Show()
        self.gauge_acq.Show()
        self._show_status_icons(None)

        self.gauge_acq.Range = self.roa_count
        self.gauge_acq.Value = 0

        # Acquire ROAs for all projects
        fs = {}
        for p in self._tab_data_model.projects.value:
            ppath = os.path.join(self.path, p.name.value)  # <acquisition date>/<project name>
            for roa in p.roas.value:
                f = fastem.acquire(roa, ppath, self._main_data_model.ebeam, self._main_data_model.multibeam,
                                   self._main_data_model.descanner, self._main_data_model.mppc,
                                   self._main_data_model.stage, self._main_data_model.ccd,
                                   self._main_data_model.beamshift, self._main_data_model.lens)
                t = roa.estimate_acquisition_time()
                fs[f] = t

        self.acq_future = model.ProgressiveBatchFuture(fs)
        self._fs_connector = ProgressiveFutureConnector(self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)
예제 #8
0
    def on_acquire(self, evt):
        """ Start the actual acquisition """
        logging.info("Acquire button clicked, starting acquisition")
        acq_streams = self.get_acq_streams()
        if not acq_streams:
            logging.info("No stream to acquire, ending immediately")
            self.on_close(
                evt)  # Nothing to do, so it's the same as closing the window

        self.acquiring = True

        # Adjust view FoV to the whole area, so that it's possible to follow the acquisition
        self._fit_view_to_area()

        self.btn_secom_acquire.Disable()

        # 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

        # For now, always indicate the best quality
        if self._main_data_model.opm:
            self._main_data_model.opm.setAcqQuality(path.ACQ_QUALITY_BEST)

        zlevels = self._get_zstack_levels()
        focus_mtd = FocusingMethod.MAX_INTENSITY_PROJECTION if zlevels else FocusingMethod.NONE

        if self.filename_tiles:
            logging.info("Acquisition tiles logged at %s", self.filename_tiles)
            os.makedirs(os.path.dirname(self.filename_tiles))

        self.acq_future = stitching.acquireTiledArea(
            acq_streams,
            self._main_data_model.stage,
            area=self.area,
            overlap=self.overlap,
            settings_obs=self._main_data_model.settings_obs,
            log_path=self.filename_tiles,
            weaver=WEAVER_COLLAGE_REVERSE,
            zlevels=zlevels,
            focusing_method=focus_mtd)
        self._acq_future_connector = ProgressiveFutureConnector(
            self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        # TODO: Build-up the complete image during the acquisition, so that the
        #       progress can be followed live.
        self.acq_future.add_done_callback(self.on_acquisition_done)

        self.btn_cancel.SetLabel("Cancel")
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel)
예제 #9
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        """
        self.update_acquisition_time(
        )  # make sure we show the right label if the previous acquisition failed
        self._main_data_model.is_acquiring.value = True
        self.btn_acquire.Enable(False)
        self.btn_cancel.Enable(True)
        self.btn_cancel.Show()
        self.gauge_acq.Show()

        self.gauge_acq.Range = len(
            self._tab_data_model.selected_scintillators.value)
        self.gauge_acq.Value = 0

        # Acquire ROAs for all projects
        acq_futures = {}
        for num in self._tab_data_model.selected_scintillators.value:
            center = self._tab_data_model.main.scintillator_positions[num]
            sz = self._tab_data_model.main.scintillator_size
            coords = (center[0] - sz[0] / 2, center[1] - sz[1] / 2,
                      center[0] + sz[0] / 2, center[1] + sz[1] / 2)
            try:
                f = fastem.acquireTiledArea(
                    self._tab_data_model.streams.value[0],
                    self._main_data_model.stage, coords)
                t = fastem.estimateTiledAcquisitionTime(
                    self._tab_data_model.streams.value[0],
                    self._main_data_model.stage, coords)
            except Exception:
                logging.exception("Failed to start overview acquisition")
                # Try acquiring the other
                continue

            f.add_done_callback(partial(self.on_acquisition_done, num=num))
            acq_futures[f] = t

        if acq_futures:
            self.acq_future = model.ProgressiveBatchFuture(acq_futures)
            self.acq_future.add_done_callback(self.full_acquisition_done)
            self._fs_connector = ProgressiveFutureConnector(
                self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        else:  # In case all acquisitions failed to start
            self._main_data_model.is_acquiring.value = False
            self._reset_acquisition_gui("Acquisition failed (see log panel).",
                                        level=logging.WARNING)
예제 #10
0
    def on_acquire(self, evt):
        """ Start the actual acquisition """
        if self.last_saved_file:  # This means the button is actually "View"
            self._view_file()
            return

        logging.info("Acquire button clicked, starting acquisition")
        self.acquiring = True

        self.btn_secom_acquire.Disable()

        # disable estimation time updates during acquisition
        self._view.lastUpdate.unsubscribe(self.on_streams_changed)

        # 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

        # For now, always indicate the best quality (even if the preset is set
        # to "live")
        if self._main_data_model.opm:
            self._main_data_model.opm.setAcqQuality(path.ACQ_QUALITY_BEST)

        # Note: It should never be possible to reach here with no streams
        streams = self.get_acq_streams()
        v_streams = self._view.getStreams()  # visible streams
        for s in streams:
            # Add extra viewable streams to view. However, do not add incompatible streams.
            if s not in v_streams and not isinstance(s, NON_SPATIAL_STREAMS):
                self._view.addStream(s)

            # Update the filename in the streams
            if hasattr(s, "filename"):
                pathname, base = os.path.split(self.filename.value)
                s.filename.value = base

        self.acq_future = acqmng.acquire(streams, self._main_data_model.settings_obs)
        self._acq_future_connector = ProgressiveFutureConnector(self.acq_future,
                                                                self.gauge_acq,
                                                                self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)

        self.btn_cancel.SetLabel("Cancel")
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel)
예제 #11
0
파일: delphi.py 프로젝트: ihebdelmic/odemis
    def __init__(self, parent, main_data, shid):
        xrcprogress_dialog.__init__(self, parent)

        # ProgressiveFuture for the ongoing calibration
        self._main_data = main_data
        self._shid = shid
        self.calib_future = None
        self._calib_future_connector = None
        self._started = False
        self.cancel_btn.Bind(wx.EVT_BUTTON, self.on_cancel)
        self.Bind(wx.EVT_CLOSE, self.on_close)
        self.info_txt.SetLabel("Calibration of the sample holder in progress")
        self.calib_future = DelphiCalibration(main_data)
        self._calib_future_connector = ProgressiveFutureConnector(
            self.calib_future, self.gauge, self.time_txt)
        self.calib_future.add_done_callback(self.on_calib_done)
        self.Fit()
예제 #12
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        Similar to win.acquisition.on_acquire()
        """
        # Time-resolved data cannot be saved in .ome.tiff format for now
        # OME-TIFF wants to save each time data on a separate "page", which causes too many pages.
        has_temporal = False
        for s in self._tab_data_model.streams.value:
            if (isinstance(s, ScannedTemporalSettingsStream) or
                isinstance(s, ScannedTCSettingsStream) or
                isinstance(s, TemporalSpectrumSettingsStream)):
                has_temporal = True

        #  ADD the the overlay (live_update) in the SEM window which displays the SEM measurements of the current
        #  acquisition if a  stream is added and acquisition is started.
        for v in self._tab_data_model.visible_views.value:
            if hasattr(v, "stream_classes") and isinstance(self._tab_data_model.semStream, v.stream_classes):
                v.addStream(self._tab_data_model.semStream)

        if (self.conf.last_format == 'TIFF' or self.conf.last_format == 'Serialized TIFF') and has_temporal:
            raise NotImplementedError("Cannot save temporal data in %s format, data format must be HDF5." \
                                      % self.conf.last_format)

        self._pause_streams()

        self.btn_acquire.Disable()
        self.btn_cancel.Enable()
        self._main_data_model.is_acquiring.value = True

        self.gauge_acq.Show()
        self.btn_cancel.Show()
        self._show_status_icons(None)
        self._tab_panel.Layout()  # to put the gauge at the right place

        # start acquisition + connect events to callback
        self.acq_future = acqmng.acquire(self._tab_data_model.acquisitionStreams, self._main_data_model.settings_obs)
        self._acq_future_connector = ProgressiveFutureConnector(self.acq_future,
                                                                self.gauge_acq,
                                                                self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)
예제 #13
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        Similar to win.acquisition.on_acquire()
        """
        self._pause_streams()

        self.btn_acquire.Disable()
        self.btn_cancel.Enable()
        self._main_data_model.is_acquiring.value = True

        self.gauge_acq.Show()
        self.btn_cancel.Show()
        self._show_status_icons(None)
        self._tab_panel.Layout()  # to put the gauge at the right place

        # start acquisition + connect events to callback
        streams = self._tab_data_model.acquisitionView.getStreams()

        self.acq_future = acq.acquire(streams)
        self._acq_future_connector = ProgressiveFutureConnector(
            self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)
예제 #14
0
    def on_acquire(self, evt):
        """ Start the actual acquisition """
        if self.last_saved_file:  # This means the button is actually "View"
            self._view_file()
            return

        logging.info("Acquire button clicked, starting acquisition")

        self.btn_secom_acquire.Disable()

        # disable estimation time updates during acquisition
        self._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._view.getStreams()

        # Add the overlay stream if the fine alignment check box is checked
        if self.chkbox_fine_align.Value:
            streams.append(self._ovrl_stream)

        # Turn off the fan to avoid vibrations (in all acquisitions)
        self._set_fan(False)

        # It should never be possible to reach here with no streams
        self.acq_future = acq.acquire(streams)
        self._acq_future_connector = ProgressiveFutureConnector(
            self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)

        self.btn_cancel.SetLabel("Cancel")
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_cancel)