Ejemplo n.º 1
0
    def update_acquisition_time(self):
        if self._ellipsis_animator:
            # cancel if there is an ellipsis animator updating the status message
            self._ellipsis_animator.cancel()
            self._ellipsis_animator = None

        # Don't update estimated time if acquisition is running (as we are
        # sharing the label with the estimated time-to-completion).
        if self._main_data_model.is_acquiring.value:
            return

        lvl = None  # icon status shown
        if self._main_data_model.is_preparing.value:
            txt = u"Optical path is being reconfigured…"
            self._ellipsis_animator = EllipsisAnimator(txt,
                                                       self.lbl_acqestimate)
            self._ellipsis_animator.start()
            lvl = logging.INFO
        elif self._roa.value == UNDEFINED_ROI:
            # TODO: update the default text to be the same
            txt = u"Region of acquisition needs to be selected"
            lvl = logging.WARN
        else:
            streams = self._tab_data_model.acquisitionStreams
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimistic
            txt = u"Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))

        logging.debug("Updating status message %s, with level %s", txt, lvl)
        self.lbl_acqestimate.SetLabel(txt)
        self._show_status_icons(lvl)
Ejemplo n.º 2
0
    def update_acquisition_time(self, _=None):
        lvl = None  # icon status shown
        if not self._tab_data_model.is_calib_done.value:
            lvl = logging.WARN
            txt = "System is not calibrated."
        elif not self._main_data_model.active_scintillators.value:
            lvl = logging.WARN
            txt = "No scintillator loaded (go to Chamber tab)."
        elif not self._tab_data_model.selected_scintillators.value:
            lvl = logging.WARN
            txt = "No scintillator selected for overview acquisition."
        else:
            acq_time = 0
            # Add up the acquisition time of all the selected scintillators
            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)
                acq_time += fastem.estimateTiledAcquisitionTime(self._tab_data_model.streams.value[0],
                                                                self._main_data_model.stage, coords)

            acq_time = math.ceil(acq_time)  # round a bit pessimistic
            txt = u"Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))
        logging.debug("Updating status message %s, with level %s", txt, lvl)
        self._set_status_message(txt, lvl)
Ejemplo n.º 3
0
def main(args):
    """
    Handles the command line arguments
    args is the list of arguments passed
    return (int): value to return to the OS as program exit code
    """
    ebeam = model.getComponent(role="e-beam")
    while ebeam.resolution.value != (1, 1):
        input("Please select spot mode and pick a point and press Enter...")

    wls = getNumber("Starting wavelength (in nm): ") * 1e-9
    wle = getNumber("Ending wavelength (in nm): ") * 1e-9
    nbp = getNumber("Number of wavelengths to acquire: ")
    dt = getNumber("Dwell time (in ms): ") * 1e-3
    exp_time = nbp * (dt + 0.05)  # 50 ms to change wavelength
    print("Expected duration: %s" %
          (units.readable_time(math.ceil(exp_time)), ))

    filename = input("Filename to store the spectrum: ")
    if "." not in filename:
        # No extension -> force hdf5
        filename += ".h5"

    print("Press Ctrl+C to cancel the acquisition")

    try:
        acquire_spec(wls, wle, int(nbp), dt, filename)
    except Exception:
        logging.exception("Unexpected error while performing action.")
        return 127

    return 0
Ejemplo n.º 4
0
    def _update_progress(self):
        """ Update the progression controls """
        now = time.time()
        past = now - self._start
        left = max(0, self._end - now)
        prev_left = self._prev_left

        # Avoid back and forth estimation (but at least every 10 s)
        can_update = True
        if prev_left is not None and self._last_update + 10 > now:
            # Don't update gauge if ratio reduces (a bit)
            try:
                ratio = past / (past + left)
                prev_ratio = self._bar.Value / self._bar.Range
                if 1 > prev_ratio / ratio > 1.1:  # decrease < 10 %
                    can_update = False
            except ZeroDivisionError:
                pass
            # Or if the time left in absolute value slightly increases (< 5s)
            if 0 < left - prev_left < 5:
                can_update = False

        if not can_update:
            logging.debug("Not updating progress as new estimation is %g s left "
                          "vs old %g s, and current ratio %g vs old %g.",
                          left, prev_left, ratio * 100, prev_ratio * 100)
            return
        else:
            self._last_update = now

        # progress bar: past / past+left
        logging.debug("updating the progress bar to %f/%f", past, past + left)
        self._bar.Range = 100 * (past + left)
        self._bar.Value = 100 * past

        if self._future.done():
            # make really sure we don't update the text after the future is over
            return

        # Time left text
        self._prev_left = left
        left = math.ceil(left)  # pessimistic

        if left > 2:
            lbl_txt = u"%s" % units.readable_time(left, full=self._full_text)
        else:
            # don't be too precise
            lbl_txt = u"a few seconds"

        if self._full_text:
            lbl_txt += u" left"

        if self._label is None:
            self._bar.SetToolTipString(lbl_txt)
        else:
            # TODO: if the text is too big for the label, rewrite with full=False
            # we could try to rely on IsEllipsized() (which requires support for
            # wxST_ELLIPSIZE_END in xrc) or dc.GetTextExtend()
            self._label.SetLabel(lbl_txt)
            self._label.Parent.Layout()
Ejemplo n.º 5
0
    def update_acquisition_time(self):
        if self._ellipsis_animator:
            # cancel if there is an ellipsis animator updating the status message
            self._ellipsis_animator.cancel()
            self._ellipsis_animator = None

        # Don't update estimated time if acquisition is running (as we are
        # sharing the label with the estimated time-to-completion).
        if self._main_data_model.is_acquiring.value:
            return

        lvl = None  # icon status shown
        if self._main_data_model.is_preparing.value:
            txt = u"Optical path is being reconfigured…"
            self._ellipsis_animator = EllipsisAnimator(txt, self.lbl_acqestimate)
            self._ellipsis_animator.start()
            lvl = logging.INFO
        elif self._roa.value == UNDEFINED_ROI:
            # TODO: update the default text to be the same
            txt = u"Region of acquisition needs to be selected"
            lvl = logging.WARN
        else:
            streams = self._tab_data_model.acquisitionStreams
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimistic
            txt = u"Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))

        logging.debug("Updating status message %s, with level %s", txt, lvl)
        self.lbl_acqestimate.SetLabel(txt)
        self._show_status_icons(lvl)
Ejemplo n.º 6
0
    def _update_calibration_controls(self, text=None, button_state=True):
        """
        Update the calibration panel controls to be ready for the next calibration.
        :param text: (None or str) A (error) message to display instead of the estimated acquisition time.
        :param button_state: (bool) Enabled or disable button depending on state. Default is enabled.
        """
        self.button.Enable(button_state)  # enable/disable button

        # TODO disable ROC overlay, so it cannot be moved while calibrating!

        if self._tab_data.is_calibrating.value:
            self.button.SetLabel("Cancel")  # indicate canceling is possible
            self.gauge.Show()  # show progress bar
        else:
            self.button.SetLabel(
                "Calibrate"
            )  # change button label back to ready for calibration
            self.gauge.Hide()  # hide progress bar

        if text is not None:
            self.label.SetLabel(text)
        else:
            duration = self.estimate_calibration_time()
            self.label.SetLabel(units.readable_time(duration, full=False))

        self.button.Parent.Layout()
Ejemplo n.º 7
0
def main(args):
    """
    Handles the command line arguments
    args is the list of arguments passed
    return (int): value to return to the OS as program exit code
    """
    ebeam = model.getComponent(role="e-beam")
    while ebeam.resolution.value != (1, 1):
        raw_input("Please select spot mode and pick a point and press Enter...")

    wls = getNumber("Starting wavelength (in nm): ") * 1e-9
    wle = getNumber("Ending wavelength (in nm): ") * 1e-9
    nbp = getNumber("Number of wavelengths to acquire: ")
    dt = getNumber("Dwell time (in ms): ") * 1e-3
    exp_time = nbp * (dt + 0.05)  # 50 ms to change wavelength
    print("Expected duration: %s" % (units.readable_time(math.ceil(exp_time)),))

    filename = raw_input("Filename to store the spectrum: ")
    if "." not in filename:
        # No extension -> force hdf5
        filename += ".h5"

    print("Press Ctrl+C to cancel the acquisition")

    try:
        acquire_spec(wls, wle, int(nbp), dt, filename)
    except Exception:
        logging.exception("Unexpected error while performing action.")
        return 127

    return 0
Ejemplo n.º 8
0
    def update_acquisition_time(self):
        """
        Must be called in the main GUI thread.
        """
        if self.acquiring:
            return

        if not self.area:
            logging.debug(
                "Unknown acquisition area, cannot estimate acquisition time")
            return

        streams = self.get_acq_streams()
        if not streams:
            acq_time = 0
        else:
            zlevels = self._get_zstack_levels()
            focus_mtd = FocusingMethod.MAX_INTENSITY_PROJECTION if zlevels else FocusingMethod.NONE
            acq_time = stitching.estimateTiledAcquisitionTime(
                streams,
                self._main_data_model.stage,
                self.area,
                self.overlap,
                zlevels=zlevels,
                focusing_method=focus_mtd)

        txt = "The estimated acquisition time is {}."
        txt = txt.format(units.readable_time(acq_time))
        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 9
0
 def _update_est_time(self, unused):
     """
     Compute and displays the estimated time for the auto centering
     """
     et = self._main_data_model.ccd.exposureTime.value
     t = align.spot.estimateAlignmentTime(et)
     t = math.ceil(t)  # round a bit pessimistic
     txt = u"~ %s" % units.readable_time(t, full=False)
     self._main_frame.lbl_auto_center.Label = txt
Ejemplo n.º 10
0
 def _update_est_time(self, _):
     """
     Compute and displays the estimated time for the auto centering
     """
     et = self._main_data_model.ccd.exposureTime.value
     t = align.spot.estimateAlignmentTime(et)
     t = math.ceil(t) # round a bit pessimistic
     txt = u"~ %s" % units.readable_time(t, full=False)
     self._tab_panel.lbl_auto_center.Label = txt
Ejemplo n.º 11
0
    def update_acquisition_time(self):
        streams = self.get_acq_streams()
        if streams:
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimisticly
            txt = "The estimated acquisition time is {}."
            txt = txt.format(units.readable_time(acq_time))
        else:
            txt = "No streams present."

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 12
0
 def _update_est_time(self):
     """
     Compute and displays the estimated time for the fine alignment
     """
     if self._tab_data_model.tool.value == guimod.TOOL_SPOT:
         dt = self._main_data_model.fineAlignDwellTime.value
         t = align.find_overlay.estimateOverlayTime(dt, self.OVRL_REPETITION)
         t = math.ceil(t) # round a bit pessimistic
         txt = u"~ %s" % units.readable_time(t, full=False)
     else:
         txt = u""
     self._tab_panel.lbl_fine_align.Label = txt
Ejemplo n.º 13
0
 def test_readable_time(self):
     #         (input) (expected output)
     values = [((1.0,), "1 second"),
               ((0,), "0 second"),
               ((3601,), "1 hour and 1 second"),
               ((12.350,), "12 seconds and 350 ms"),
               ((3 * 24 * 60 * 60 + 12 * 60,), "3 days and 12 minutes"),
               ]
     for (i, eo) in values:
         o = units.readable_time(*i)
         self.assertEquals(o, eo,
                           u"%s is '%s' while expected '%s'" % (i, o, eo))
Ejemplo n.º 14
0
 def test_readable_time(self):
     #         (input) (expected output)
     values = [((1.0,), "1 second"),
               ((0,), "0 second"),
               ((3601,), "1 hour and 1 second"),
               ((12.350,), "12 seconds and 350 ms"),
               ((3 * 24 * 60 * 60 + 12 * 60,), "3 days and 12 minutes"),
               ]
     for (i, eo) in values:
         o = units.readable_time(*i)
         self.assertEquals(o, eo,
                           u"%s is '%s' while expected '%s'" % (i, o, eo))
Ejemplo n.º 15
0
 def _update_est_time(self):
     """
     Compute and displays the estimated time for the fine alignment
     """
     if self._tab_data_model.tool.value == guimod.TOOL_SPOT:
         dt = self._main_data_model.fineAlignDwellTime.value
         t = align.find_overlay.estimateOverlayTime(dt, self.OVRL_REPETITION)
         t = math.ceil(t) # round a bit pessimistic
         txt = u"~ %s" % units.readable_time(t, full=False)
     else:
         txt = u""
     self._tab_panel.lbl_fine_align.Label = txt
Ejemplo n.º 16
0
    def _update_progress(self):
        if self._start is None:  # no info yet
            return

        now = time.time()
        past = now - self._start
        left = max(0, self._end - now)
        self._prev_left, prev_left = left, self._prev_left

        # progress bar: past / past+left
        can_update = True
        try:
            ratio = past / (past + left)
            # Don't update gauge if ratio reduces
            prev_ratio = self._bar.Value / self._bar.Range
            logging.debug("current ratio %g, old ratio %g", ratio * 100,
                          prev_ratio * 100)
            if (prev_left is not None
                    and prev_ratio - 0.1 < ratio < prev_ratio):
                can_update = False
        except ZeroDivisionError:
            pass

        if can_update:
            logging.debug("updating the progress bar to %f/%f", past,
                          past + left)
            self._bar.Range = 100 * (past + left)
            self._bar.Value = 100 * past

        if self._future.done():
            # make really sure we don't update the text after the future is over
            return

        # Time left
        left = math.ceil(left)  # pessimistic
        # Avoid back and forth estimation => don't increase unless really huge (> 5s)
        if (prev_left is not None and 0 < left - prev_left < 5):
            logging.debug(
                "No updating progress bar as new estimation is %g s "
                "while the previous was only %g s", left, prev_left)
            return

        if left > 2:
            lbl_txt = "%s left." % units.readable_time(left)
        else:
            # don't be too precise
            lbl_txt = "a few seconds left."

        if self._label is None:
            self._bar.SetToolTipString(lbl_txt)
        else:
            self._label.SetLabel(lbl_txt)
Ejemplo n.º 17
0
    def update_acquisition_time(self):
        streams = self._view.getStreams()
        if streams:
            if self.chkbox_fine_align.Value:
                streams.append(self._ovrl_stream)
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimisticly
            txt = "The estimated acquisition time is {}."
            txt = txt.format(units.readable_time(acq_time))
        else:
            txt = "No streams present."

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 18
0
    def update_acquisition_time(self):

        if self._roa.value == UNDEFINED_ROI:
            # TODO: update the default text to be the same
            txt = "Region of acquisition needs to be selected"
        else:
            streams = self._tab_data_model.acquisitionView.getStreams()
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time) # round a bit pessimistic
            txt = "Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 19
0
    def update_acquisition_time(self):
        streams = self._view.getStreams()
        if streams:
            if self.chkbox_fine_align.Value:
                streams.append(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)
Ejemplo n.º 20
0
    def update_acquisition_time(self):

        if self._roa.value == UNDEFINED_ROI:
            # TODO: update the default text to be the same
            txt = "Region of acquisition needs to be selected"
        else:
            streams = self._tab_data_model.acquisitionView.getStreams()
            acq_time = acq.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimistic
            txt = "Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 21
0
    def _update_progress(self):
        if self._start is None: # no info yet
            return

        now = time.time()
        past = now - self._start
        left = max(0, self._end - now)
        self._prev_left, prev_left = left, self._prev_left

        # progress bar: past / past+left
        can_update = True
        try:
            ratio = past / (past + left)
            # Don't update gauge if ratio reduces
            prev_ratio = self._bar.Value / self._bar.Range
            logging.debug("current ratio %g, old ratio %g", ratio * 100, prev_ratio * 100)
            if (prev_left is not None and
                prev_ratio - 0.1 < ratio < prev_ratio):
                can_update = False
        except ZeroDivisionError:
            pass

        if can_update:
            logging.debug("updating the progress bar to %f/%f", past, past + left)
            self._bar.Range = 100 * (past + left)
            self._bar.Value = 100 * past


        if self._future.done():
            # make really sure we don't update the text after the future is over
            return

        # Time left
        left = math.ceil(left) # pessimistic
        # Avoid back and forth estimation => don't increase unless really huge (> 5s)
        if (prev_left is not None and 0 < left - prev_left < 5):
            logging.debug("No updating progress bar as new estimation is %g s "
                          "while the previous was only %g s",
                          left, prev_left)
            return

        if left > 2:
            lbl_txt = "%s left." % units.readable_time(left)
        else:
            # don't be too precise
            lbl_txt = "a few seconds left."

        if self._label is None:
            self._bar.SetToolTipString(lbl_txt)
        else:
            self._label.SetLabel(lbl_txt)
Ejemplo n.º 22
0
    def update_acquisition_time(self):
        """
        Must be called in the main GUI thread.
        """
        streams = self.get_acq_streams()
        if streams:
            acq_time = acqmng.estimateTime(streams)
            acq_time = math.ceil(acq_time)  # round a bit pessimisticly
            txt = "The estimated acquisition time is {}."
            txt = txt.format(units.readable_time(acq_time))
        else:
            txt = "No streams present."

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 23
0
    def update_acquisition_time(self, acq_time=999):
        """
        Must be called in the main GUI thread.
        """
        if not self.acquiring:
            streams = self.get_acq_streams()
            if not streams:
                acq_time = 0
            else:
                acq_time = stitching.estimateTiledAcquisitionTime(streams,
                                                              self._main_data_model.stage,
                                                              self.area, self.overlap,
                                                              zlevels=self._get_zstack_levels())

        txt = "The estimated acquisition time is {}."
        txt = txt.format(units.readable_time(acq_time))

        self.lbl_acqestimate.SetLabel(txt)
Ejemplo n.º 24
0
    def update_acquisition_time(self):
        # Update path (in case it's already the next day)
        self.path = datetime.today().strftime('%Y-%m-%d')
        self._tab_panel.txt_destination.SetValue(self.path)

        lvl = None  # icon status shown
        if not self._tab_data_model.is_calib_1_done.value \
                or not self._tab_data_model.is_calib_2_done.value \
                or not self._tab_data_model.is_calib_3_done.value:
            lvl = logging.WARN
            txt = "System is not calibrated."
        elif self.roa_count == 0:
            lvl = logging.WARN
            txt = "No region of acquisition selected."
        elif self._get_undefined_calibrations_2():
            lvl = logging.WARN
            txt = "Calibration regions %s missing." % (", ".join(
                str(c) for c in self._get_undefined_calibrations_2()), )
        elif self._get_undefined_calibrations_3():
            lvl = logging.WARN
            txt = "Calibration regions %s missing." % (", ".join(
                str(c) for c in self._get_undefined_calibrations_3()), )
        else:
            # Don't update estimated time if acquisition is running (as we are
            # sharing the label with the estimated time-to-completion).
            if self._main_data_model.is_acquiring.value:
                return
            # Display acquisition time
            projects = self._tab_data_model.projects.value
            acq_time = 0
            for p in projects:
                for roa in p.roas.value:
                    acq_time += estimate_acquisition_time(
                        roa, [
                            Calibrations.OPTICAL_AUTOFOCUS,
                            Calibrations.IMAGE_TRANSLATION_PREALIGN
                        ])
            acq_time = math.ceil(acq_time)  # round a bit pessimistic
            txt = u"Estimated time is {}."
            txt = txt.format(units.readable_time(acq_time))
        logging.debug("Updating status message %s, with level %s", txt, lvl)
        self.lbl_acqestimate.SetLabel(txt)
        self._show_status_icons(lvl)
Ejemplo n.º 25
0
    def acquire(self, fn):
        self.save_hw_settings()

        # it's not possible to keep in memory all the CCD images, so we save
        # them one by one in separate files (fn-ccd-XXXX.tiff)
        fn_base, fn_ext = os.path.splitext(fn)

        try:
            cycles = 1

            anchor = self.anchor

            logging.info("Target ROI is [{:.3f},{:.3f},{:.3f},{:.3f}]".format(
                *self.roi))

            rep = self.calc_rep(self.roi)  # returns nr of SR pixels in x,y
            rep = self.check_gridpitch(rep, self.gridpitch)

            roi = self.update_roi(self.roi, rep)
            logging.info(
                "Updated ROI to [{:.3f},{:.3f},{:.3f},{:.3f}], in order to fit integer number of SR spots"
                .format(*roi))

            spots = self.calc_xy_pos(roi, rep)  # spots are defined
            shape = spots.shape[0:2]

            logging.info("Will scan %d x %d pixels.", shape[1], shape[0])
            logging.info("Using %d x %d gridscans.", self.gridpitch[0],
                         self.gridpitch[1])

            dur = self.estimate_acq_time(shape)
            logging.info("Estimated acquisition time: %s",
                         units.readable_time(round(dur)))

            # Let's go!
            logging.info("Acquiring full image 0")
            self.acquire_and_save_optical_survey(fn, "fullBefore")

            logging.info("Starting with bleaching a border around the ROI")
            sem_border = self.bleach_borders(roi)
            self.save_data(sem_border,
                           "%s-SEM_bleached_border%s" % (fn_base, fn_ext))

            ccd_roi = self.sem_roi_to_ccd(roi)
            ccd_roi = [
                ccd_roi[0] - MARGIN_ACQ, ccd_roi[1] - MARGIN_ACQ,
                ccd_roi[2] + MARGIN_ACQ, ccd_roi[3] + MARGIN_ACQ
            ]
            ccd_roi_idx = (
                slice(ccd_roi[1],
                      ccd_roi[3] + 1), slice(ccd_roi[0], ccd_roi[2] + 1)
            )  # + 1 because we want to include the corners of the ROI

            self.configure_ccd(ccd_roi)
            self.configure_sem_for_tile()

            # start with the original fluorescence count (no bleaching)
            ccd_data = self.get_fluo_image()
            ccd_data_to_save = ccd_data[ccd_roi_idx]

            # Set up the drift correction (using the dwell time used for overview)
            if anchor:
                logging.info("Starting with pre-exposing the anchor region")
                de = drift.AnchoredEstimator(self.ebeam, self.sed, anchor,
                                             self.dtsem)
                for ii in range(13):
                    de.acquire()

                de = drift.AnchoredEstimator(self.ebeam, self.sed, anchor,
                                             self.dtsem)
                px_iter = de.estimateCorrectionPeriod(self.dperiod, 1.0,
                                                      self.gridpitch)
                de.acquire()  # original anchor region
                self.save_data(
                    de.raw[-1],
                    "%s%02d-driftAnchor-%05d%s" % (fn_base, 0, 0, fn_ext))
                self.driftlog = [(0, 0)]
                self.drifttime = [time.time()]

                next_dc = px_iter.next()

            for ii in range(cycles):
                # TODO: fix this super-arbitrary dwell time change
                if ii >= 1:
                    self.ebeam.dwellTime.value = 2 * self.dt

                n = 0
                sem_data = []

                # save the fluorescence without bleaching (or end of previous cycle)
                self.save_data(ccd_data_to_save,
                               "%s%02d-ccd-%05d%s" % (fn_base, ii, n, fn_ext))
                for g in numpy.ndindex(self.gridpitch):
                    n += 1

                    spotssubset = spots[g[0]::self.gridpitch[0],
                                        g[1]::self.gridpitch[1], :]
                    subsetshape = spotssubset.shape[0:2]

                    dur_frame = self.estimate_acq_time_gridscan(subsetshape)
                    overhead_est = 1 * dur_frame + 0.1

                    self.ccd.exposureTime.value = dur_frame + overhead_est
                    logging.info(
                        "Setting exposuretime for spotsimage to: %s (includes %s overhead)",
                        units.readable_time((dur_frame + overhead_est)),
                        units.readable_time((overhead_est)))
                    self.ccd_acq_complete.clear()
                    self.ccd.data.subscribe(self.on_ccd_data)
                    time.sleep(0.2)

                    logging.info(
                        "Bleaching pixels (%d,%d) + (%d,%d)*(0 -> %d, 0 -> %d)",
                        g[1], g[0], self.gridpitch[1], self.gridpitch[0],
                        subsetshape[1] - 1, subsetshape[0] - 1)
                    for i in numpy.ndindex(subsetshape):
                        bl_subset = self.bleach_spot(spotssubset[i].tolist())
                        sem_data.append(bl_subset)

                    self.ccd_acq_complete.wait()
                    if self.ccd_acq_complete.is_set():
                        logging.info("SEM bleaching took longer than expected")

                    spotsimage_to_save = self._spotsimage[ccd_roi_idx]
                    self.save_data(
                        spotsimage_to_save,
                        "%s%02d-spots-%05d%s" % (fn_base, ii, n, fn_ext))

                    ccd_data = self.get_fluo_image()
                    # ccd_data_to_save = ccd_data
                    ccd_data_to_save = ccd_data[ccd_roi_idx]
                    self.save_data(
                        ccd_data_to_save,
                        "%s%02d-ccd-%05d%s" % (fn_base, ii, n, fn_ext))

                    if anchor:
                        # Check whether the drift-correction needs to take place
                        if n >= next_dc:
                            de.acquire()  # take a new
                            d = de.estimate()

                            self.drift = (self.drift[0] + d[0],
                                          self.drift[1] + d[1])
                            logging.info(
                                "Drift estimated to {:.1f}, {:.1f} px".format(
                                    *self.drift))
                            next_dc = n + px_iter.next()

                            self.save_data(
                                de.raw[-1], "%s%02d-driftAnchor-%05d%s" %
                                (fn_base, ii, n, fn_ext))

                            self.drifttime.append(time.time())
                            self.driftlog.append(self.drift)

                # Reconstruct the complete images
                logging.info("Reconstructing SEM image from tiles")
                sem_array = numpy.array(
                    sem_data)  # put everything in a big array
                sem_final = self.assemble_tiles(shape, sem_array, roi,
                                                self.gridpitch)
                sem_final.metadata[model.MD_DWELL_TIME] = self.dt
                sem_final.metadata[model.MD_DESCRIPTION] = "SEM"
                self.save_data(
                    sem_final,
                    "%s%02d_SEM_during_scan%s" % (fn_base, ii, fn_ext))

                # acquire a full image again after bleaching
            logging.info("Acquiring full image 1")
            self.acquire_and_save_optical_survey(fn, "fullAfter")

            if anchor:
                de.acquire()  # take a new
                d = de.estimate()

                self.drift = (self.drift[0] + d[0], self.drift[1] + d[1])
                logging.info(
                    "Drift estimated to {:.1f}, {:.1f} px".format(*self.drift))
                self.save_data(de.raw[-1],
                               "%s-driftAnchor-final%s" % (fn_base, fn_ext))

            # take the SEM image again with specified dwell time and step size
            logging.info("Acquiring SEM survey")
            sem_survey_data = self.acquire_sem_survey(roi)
            sem_survey_data.metadata[model.MD_DESCRIPTION] = "SEM survey"
            self.save_data(sem_survey_data,
                           "%s_SEM_survey%s" % (fn_base, fn_ext))

        finally:
            self.resume_hw_settings()
            self.light.power.value = self.light.power.range[
                0]  # makes sure light won't stay on
Ejemplo n.º 26
0
 def value_formatter(value):
     value_ctrl.SetValue(readable_time(value, full=False))
Ejemplo n.º 27
0
    def update_calibration_time(self, time):
        txt = "Time remaining: {}"
        txt = txt.format(units.readable_time(time))

        self.time_txt.SetLabel(txt)
Ejemplo n.º 28
0
    def update_calibration_time(self, time):
        txt = "Time remaining: {}"
        txt = txt.format(units.readable_time(time))

        self.time_txt.SetLabel(txt)
Ejemplo n.º 29
0
    def acquire(self, fn):
        self.save_hw_settings()

        # it's not possible to keep in memory all the CCD images, so we save
        # them one by one in separate files (fn-ccd-XXXX.h5)
        fn_base, fn_ext = os.path.splitext(fn)

        try:
            spots = self.calc_xy_pos(self.roi, self.pxs)
            shape = spots.shape[0:2]
            logging.info("Will scan %d x %d pixels.", shape[1], shape[0])

            ccd_roi = self.sem_roi_to_ccd(self.roi)
            self.configure_ccd(ccd_roi)
            self.configure_sem_for_tile()

            dur = self.estimate_acq_time(shape)
            logging.info("Estimated acquisition time: %s",
                         units.readable_time(round(dur)))

            # TODO: acquire a "Optical survey" image?

            # Let's go!
            sem_data = []
            # start with the original fluorescence count (no bleaching)

            n = 0
            ccd_data = self.get_fluo_image()
            self.save_data(ccd_data, "%s-ccd-%05d%s" % (fn_base, n, fn_ext))
            ccd_count = [self.ccd_image_to_count(ccd_data, ccd_roi)]
            try:
                # TODO: support drift correction (cf ar_spectral_ph)
                for i in numpy.ndindex(shape):
                    logging.info("Acquiring pixel %d,%d", i[1], i[0])
                    sem_data.append(self.bleach_spot(spots[i].tolist()))
                    ccd_data = self.get_fluo_image()
                    n += 1
                    self.save_data(ccd_data,
                                   "%s-ccd-%05d%s" % (fn_base, n, fn_ext))
                    ccd_count.append(self.ccd_image_to_count(
                        ccd_data, ccd_roi))

                # TODO: acquire a "SEM survey" image?

                # Reconstruct the complete images
                logging.info("Reconstructing final images")
                sem_array = numpy.array(
                    sem_data)  # put everything in a big array
                sem_final = self.assemble_tiles(shape, sem_array, self.roi,
                                                self.pxs)
                sem_final.metadata[model.MD_DWELL_TIME] = self.dt
                sem_final.metadata[model.MD_DESCRIPTION] = "SEM"

                # compute the diff
                ccd_count = numpy.array(ccd_count)  # force to be one big array
                ccd_diff = ccd_count[0:-1] - ccd_count[1:]
                ccd_diff.shape += (1, 1
                                   )  # add info that each element is one pixel
                ccd_final = self.assemble_tiles(shape, ccd_diff, self.roi,
                                                self.pxs)
                ccd_md = self.ccd.getMetadata()
                ccd_final.metadata[model.MD_IN_WL] = ccd_md[model.MD_IN_WL]
                ccd_final.metadata[model.MD_DESCRIPTION] = "Light diff"


#                 ccd_data = model.DataArray(ccd_data)
#                 ccd_data.metadata[model.MD_EXP_TIME] = self.ccd.exposureTime.value
#                 ccd_data.metadata[model.MD_DESCRIPTION] = "Raw CCD intensity"
            except Exception:
                # TODO: try to save the data as is
                raise

            # Save the data
            data = [sem_final, ccd_final]
            self.save_data(data, fn)
        finally:
            self.resume_hw_settings()
Ejemplo n.º 30
0
    def _update_progress(self):
        """ Update the progression controls """
        now = time.time()
        past = now - self._start
        left = max(0, self._end - now)
        prev_left = self._prev_left

        # Avoid back and forth estimation (but at least every 10 s)
        can_update = True
        if prev_left is not None and self._last_update + 10 > now:
            # Don't update gauge if ratio reduces (a bit)
            try:
                ratio = past / (past + left)
                prev_ratio = self._bar.Value / self._bar.Range
                if 1 > prev_ratio / ratio > 1.1:  # decrease < 10 %
                    can_update = False
            except ZeroDivisionError:
                pass
            # Or if the time left in absolute value slightly increases (< 5s)
            if 0 < left - prev_left < 5:
                can_update = False

        if not can_update:
            logging.debug(
                "Not updating progress as new estimation is %g s left "
                "vs old %g s, and current ratio %g vs old %g.", left,
                prev_left, ratio * 100, prev_ratio * 100)
            return
        else:
            self._last_update = now

        # progress bar: past / past+left
        # logging.debug("updating the progress bar to %f/%f", past, past + left)
        self._bar.Range = 100 * (past + left)
        self._bar.Value = 100 * past

        if self._future.done():
            # Make sure we don't update the lbl_txt after the future is over as
            # it might be used to display other information
            return

        # Time left text
        self._prev_left = left
        left = math.ceil(left)  # pessimistic

        if left > 2:
            lbl_txt = u"%s" % units.readable_time(left, full=self._full_text)
        else:
            # don't be too precise
            lbl_txt = u"a few seconds"

        if self._full_text:
            lbl_txt += u" left"

        if self._label is None:
            self._bar.SetToolTipString(lbl_txt)
        else:
            # TODO: if the text is too big for the label, rewrite with full=False
            # we could try to rely on IsEllipsized() (which requires support for
            # wxST_ELLIPSIZE_END in xrc) or dc.GetTextExtend()
            self._label.SetLabel(lbl_txt)
            self._label.Parent.Layout()
Ejemplo n.º 31
0
    def acquire(self, fn):
        self.save_hw_settings()
        
        # it's not possible to keep in memory all the CCD images, so we save
        # them one by one in separate files (fn-ccd-XXXX.h5)
        fn_base, fn_ext = os.path.splitext(fn)

        try:
            spots = self.calc_xy_pos(self.roi, self.pxs)
            shape = spots.shape[0:2]
            logging.info("Will scan %d x %d pixels.", shape[1], shape[0])
            
            ccd_roi = self.sem_roi_to_ccd(self.roi)
            self.configure_ccd(ccd_roi)
            self.configure_sem_for_tile()
            
            dur = self.estimate_acq_time(shape)
            logging.info("Estimated acquisition time: %s",
                         units.readable_time(round(dur)))
            
            # TODO: acquire a "Optical survey" image?

            # Let's go!
            sem_data = []
            # start with the original fluorescence count (no bleaching)

            n = 0
            ccd_data = self.get_fluo_image()
            self.save_data(ccd_data, "%s-ccd-%05d%s" % (fn_base, n, fn_ext))
            ccd_count = [self.ccd_image_to_count(ccd_data, ccd_roi)]
            try:
                # TODO: support drift correction (cf ar_spectral_ph)
                for i in numpy.ndindex(shape):
                    logging.info("Acquiring pixel %d,%d", i[1], i[0])
                    sem_data.append(self.bleach_spot(spots[i].tolist()))
                    ccd_data = self.get_fluo_image()
                    n += 1
                    self.save_data(ccd_data, "%s-ccd-%05d%s" % (fn_base, n, fn_ext))
                    ccd_count.append(self.ccd_image_to_count(ccd_data, ccd_roi))
                
                # TODO: acquire a "SEM survey" image?
                 
                # Reconstruct the complete images
                logging.info("Reconstructing final images")
                sem_array = numpy.array(sem_data) # put everything in a big array
                sem_final = self.assemble_tiles(shape, sem_array, self.roi, self.pxs)
                sem_final.metadata[model.MD_DWELL_TIME] = self.dt
                sem_final.metadata[model.MD_DESCRIPTION] = "SEM"
                
                # compute the diff
                ccd_count = numpy.array(ccd_count) # force to be one big array
                ccd_diff = ccd_count[0:-1] - ccd_count[1:]
                ccd_diff.shape += (1, 1) # add info that each element is one pixel
                ccd_final = self.assemble_tiles(shape, ccd_diff, self.roi, self.pxs)
                ccd_md = self.ccd.getMetadata()
                ccd_final.metadata[model.MD_IN_WL] = ccd_md[model.MD_IN_WL]
                ccd_final.metadata[model.MD_DESCRIPTION] = "Light diff"
                
#                 ccd_data = model.DataArray(ccd_data)
#                 ccd_data.metadata[model.MD_EXP_TIME] = self.ccd.exposureTime.value
#                 ccd_data.metadata[model.MD_DESCRIPTION] = "Raw CCD intensity"
            except Exception:
                # TODO: try to save the data as is
                raise
            
            # Save the data
            data = [sem_final, ccd_final]
            self.save_data(data, fn)
        finally:
            self.resume_hw_settings()