Esempio n. 1
0
    def test_simple(self):
        # create a simple streamTree
        st = stream.StreamTree(streams=[self.streams[0]])
        f = acq.acquire(st.getStreams())
        data = f.result()
        self.assertIsInstance(data[0], model.DataArray)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        # let's do it a second time, "just for fun"
        f = acq.acquire(st.getStreams())
        data = f.result()
        self.assertIsInstance(data[0], model.DataArray)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)
Esempio n. 2
0
    def test_sync_sem_ccd(self):
        """
        try acquisition with fairly complex SEM/CCD stream
        """
        # Create the streams and streamTree
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data,
                                  self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data,
                                self.ebeam)
        ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data,
                                      self.ebeam)
        semars = stream.SEMARMDStream("test SEM/AR", [sems, ars])
        st = stream.StreamTree(streams=[semsur, semars])

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng)  # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1  # s
        ars.repetition.value = (2, 3)
        num_ar = numpy.prod(ars.repetition.value)

        est_time = acq.estimateTime(st.getProjections())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getProjections())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time /
                                2)  # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 2)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1)  # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(not f.cancelled())

        time.sleep(0.1)
        self.assertEqual(self.done, 1)
Esempio n. 3
0
 def _export_to_file(self, acq_future):
     """
     return (list of DataArray, filename): data exported and filename
     """
     st = self._tab_data_model.acquisitionView.stream_tree
     thumb = acq.computeThumbnail(st, acq_future)
     data = acq_future.result()
     filename = self.filename.value
     exporter = dataio.get_exporter(self.conf.last_format)
     exporter.export(filename, data, thumb)
     logging.info(u"Acquisition saved as file '%s'.", filename)
     return data, filename
Esempio n. 4
0
    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")
Esempio n. 5
0
    def test_sync_sem_ccd(self):
        """
        try acquisition with fairly complex SEM/CCD stream
        """
        # Create the streams and streamTree
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data, self.ebeam)
        ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam)
        semars = stream.SEMARMDStream("test SEM/AR", [sems, ars])
        st = stream.StreamTree(streams=[semsur, semars])

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng) # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1 # s
        ars.repetition.value = (2, 3)
        num_ar = numpy.prod(ars.repetition.value)

        est_time = acq.estimateTime(st.getProjections())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getProjections())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time / 2) # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 2)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1) # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(not f.cancelled())

        time.sleep(0.1)
        self.assertEqual(self.done, 1)
Esempio n. 6
0
    def _export_to_file(self, acq_future):
        """
        return (list of DataArray, filename): data exported and filename
        """
        st = self._tab_data_model.acquisitionView.stream_tree
        thumb = acq.computeThumbnail(st, acq_future)
        data, exp = acq_future.result()

        # Handle the case acquisition failed "a bit"
        if exp:
            logging.error("Acquisition failed (after %d streams): %s",
                          len(data), exp)

        filename = self.filename.value
        exporter = dataio.get_converter(self.conf.last_format)
        exporter.export(filename, data, thumb)
        logging.info(u"Acquisition saved as file '%s'.", filename)
        return data, exp, filename
Esempio n. 7
0
    def _export_to_file(self, acq_future):
        """
        return (list of DataArray, filename): data exported and filename
        """
        st = self._tab_data_model.acquisitionView.stream_tree
        thumb = acq.computeThumbnail(st, acq_future)
        data, exp = acq_future.result()

        if data:
            filename = self.filename.value
            exporter = dataio.get_converter(self.conf.last_format)
            exporter.export(filename, data, thumb)
            logging.info(u"Acquisition saved as file '%s'.", filename)
        else:
            logging.debug("Not saving into file '%s' as there is no data",
                          filename)

        return data, exp, filename
Esempio n. 8
0
    def _export_to_file(self, acq_future):
        """
        return (list of DataArray, filename): data exported and filename
        """
        streams = list(self._tab_data_model.acquisitionStreams)
        st = acq.stream.StreamTree(streams=streams)
        thumb = acq.computeThumbnail(st, acq_future)
        data, exp = acq_future.result()

        if data:
            filename = self.filename.value
            exporter = dataio.get_converter(self.conf.last_format)
            exporter.export(filename, data, thumb)
            logging.info(u"Acquisition saved as file '%s'.", filename)
        else:
            logging.debug("Not saving into file '%s' as there is no data", filename)

        return data, exp, filename
Esempio n. 9
0
    def _export_to_file(self, acq_future):
        """
        return (list of DataArray, filename): data exported and filename
        """
        st = self._tab_data_model.acquisitionView.stream_tree
        thumb = acq.computeThumbnail(st, acq_future)
        data, exp = acq_future.result()

        # Handle the case acquisition failed "a bit"
        if exp:
            logging.error("Acquisition failed (after %d streams): %s",
                          len(data), exp)

        filename = self.filename.value
        exporter = dataio.get_converter(self.conf.last_format)
        exporter.export(filename, data, thumb)
        logging.info(u"Acquisition saved as file '%s'.", filename)
        return data, exp, filename
Esempio n. 10
0
    def on_acquisition_done(self, future):
        """ Callback called when the acquisition is finished (either successfully or cancelled) """
        self._set_fan(True)  # Turn the fan back on

        # bind button back to direct closure
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close)
        self._resume_settings()

        # re-enable estimation time updates
        self._view.lastUpdate.subscribe(self.on_streams_changed)

        try:
            data, exp = 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.")
            self.lbl_acqestimate.Parent.Layout()
            # leave the gauge, to give a hint on what went wrong.
            return

        # Handle the case acquisition failed "a bit"
        if exp:
            logging.error("Acquisition failed (after %d streams): %s",
                          len(data), exp)

        # save result to file
        self.lbl_acqestimate.SetLabel("Saving file...")
        self.lbl_acqestimate.Parent.Layout()
        try:
            thumb = acq.computeThumbnail(self._view.stream_tree, future)
            filename = self.filename.value
            exporter = dataio.get_converter(self.conf.last_format)
            exporter.export(filename, data, thumb)
            logging.info("Acquisition saved as file '%s'.", filename)
            # Allow to see the acquisition
            self.btn_secom_acquire.SetLabel("VIEW")
            self.last_saved_file = filename
        except Exception:
            logging.exception("Saving acquisition failed")
            self.btn_secom_acquire.Enable()
            self.lbl_acqestimate.SetLabel("Saving acquisition file failed.")
            self.lbl_acqestimate.Parent.Layout()
            return

        if exp:
            self.lbl_acqestimate.SetLabel("Acquisition failed (partially).")
        else:
            self.lbl_acqestimate.SetLabel("Acquisition completed.")
            # As the action is complete, rename "Cancel" to "Close"
            self.btn_cancel.SetLabel("Close")
        self.lbl_acqestimate.Parent.Layout()

        # Make sure the file is not overridden
        self.btn_secom_acquire.Enable()
Esempio n. 11
0
    def on_acquisition_done(self, future):
        """ Callback called when the acquisition is finished (either successfully or cancelled) """
        if self._main_data_model.opm:
            self._main_data_model.opm.setAcqQuality(path.ACQ_QUALITY_FAST)

        # bind button back to direct closure
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close)
        self._resume_settings()

        self.acquiring = False

        # re-enable estimation time updates
        self._view.lastUpdate.subscribe(self.on_streams_changed)

        self.acq_future = None  # To avoid holding the ref in memory
        self._acq_future_connector = None

        try:
            data, exp = future.result(1)  # timeout is just for safety
            self.conf.fn_count = update_counter(self.conf.fn_count)
        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.")
            self.lbl_acqestimate.Parent.Layout()
            # leave the gauge, to give a hint on what went wrong.
            return

        # Handle the case acquisition failed "a bit"
        if exp:
            logging.warning("Acquisition failed (after %d streams): %s",
                            len(data), exp)

        # save result to file
        self.lbl_acqestimate.SetLabel("Saving file...")
        self.lbl_acqestimate.Parent.Layout()
        try:
            thumb = acq.computeThumbnail(self._view.stream_tree, future)
            filename = self.filename.value
            exporter = dataio.get_converter(self.conf.last_format)
            exporter.export(filename, data, thumb)
            logging.info("Acquisition saved as file '%s'.", filename)
            # Allow to see the acquisition
            self.btn_secom_acquire.SetLabel("VIEW")
            self.last_saved_file = filename
        except Exception:
            logging.exception("Saving acquisition failed")
            self.btn_secom_acquire.Enable()
            self.lbl_acqestimate.SetLabel("Saving acquisition file failed.")
            self.lbl_acqestimate.Parent.Layout()
            return

        if exp:
            self.lbl_acqestimate.SetLabel("Acquisition failed (partially).")
        else:
            self.lbl_acqestimate.SetLabel("Acquisition completed.")
            # As the action is complete, rename "Cancel" to "Close"
            self.btn_cancel.SetLabel("Close")
        self.lbl_acqestimate.Parent.Layout()

        # Make sure the file is not overridden
        self.btn_secom_acquire.Enable()
Esempio n. 12
0
    def test_leech(self):
        """
        try acquisition with leech
        """
        # Create the streams and streamTree
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data,
                                  self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data,
                                self.ebeam)
        ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data,
                                      self.ebeam)
        semars = stream.SEMARMDStream("test SEM/AR", [sems, ars])
        st = stream.StreamTree(streams=[semsur, semars])

        pcd = Fake0DDetector("test")
        pca = ProbeCurrentAcquirer(pcd)
        sems.leeches.append(pca)
        semsur.leeches.append(pca)

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng)  # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1  # s
        ars.repetition.value = (2, 3)
        num_ar = numpy.prod(ars.repetition.value)

        pca.period.value = 10  # Only at beginning and end

        est_time = acq.estimateTime(st.getProjections())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getProjections())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time /
                                2)  # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 2)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1)  # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(not f.cancelled())

        time.sleep(0.1)
        self.assertEqual(self.done, 1)

        for da in data:
            pcmd = da.metadata[model.MD_EBEAM_CURRENT_TIME]
            self.assertEqual(len(pcmd), 2)
Esempio n. 13
0
    def test_sync_path_guess(self):
        """
        try synchronized acquisition using the Optical Path Manager
        """
        # Create the streams and streamTree
        opmngr = path.OpticalPathManager(self.microscope)
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data,
                                  self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data,
                                self.ebeam)
        ars = stream.ARSettingsStream("test ar",
                                      self.ccd,
                                      self.ccd.data,
                                      self.ebeam,
                                      opm=opmngr)
        semars = stream.SEMARMDStream("test SEM/AR", [sems, ars])
        specs = stream.SpectrumSettingsStream("test spec",
                                              self.spec,
                                              self.spec.data,
                                              self.ebeam,
                                              opm=opmngr)
        sps = stream.SEMSpectrumMDStream("test sem-spec", [sems, specs])
        st = stream.StreamTree(streams=[semsur, semars, sps])

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR/SPEC settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        specs.roi.value = (0.2, 0.2, 0.7, 0.7)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng)  # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1  # s
        ars.repetition.value = (2, 3)
        specs.repetition.value = (3, 2)
        num_ar = numpy.prod(ars.repetition.value)

        est_time = acq.estimateTime(st.getProjections())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getProjections())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time /
                                2)  # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 4)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1)  # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(not f.cancelled())

        # assert optical path configuration
        exp_pos = path.SPARC_MODES["spectral"][1]
        self.assertEqual(self.lenswitch.position.value, exp_pos["lens-switch"])
        self.assertEqual(self.spec_det_sel.position.value,
                         exp_pos["spec-det-selector"])
        self.assertEqual(self.ar_spec_sel.position.value,
                         exp_pos["ar-spec-selector"])

        time.sleep(0.1)
        self.assertEqual(self.done, 1)
Esempio n. 14
0
    def test_sync_path_guess(self):
        """
        try synchronized acquisition using the Optical Path Manager
        """
        # Create the streams and streamTree
        opmngr = path.OpticalPathManager(self.microscope)
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data, self.ebeam)
        ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam, opm=opmngr)
        semars = stream.SEMARMDStream("test SEM/AR", sems, ars)
        specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam, opm=opmngr)
        sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs)
        st = stream.StreamTree(streams=[semsur, semars, sps])

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR/SPEC settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        specs.roi.value = (0.2, 0.2, 0.7, 0.7)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng) # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1 # s
        ars.repetition.value = (2, 3)
        specs.repetition.value = (3, 2)
        num_ar = numpy.prod(ars.repetition.value)

        est_time = acq.estimateTime(st.getStreams())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getStreams())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time / 2) # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 4)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1) # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertEqual(self.done, 1)
        self.assertTrue(not f.cancelled())

        # assert optical path configuration
        exp_pos = path.SPARC_MODES["spectral"][1]
        self.assertEqual(self.lenswitch.position.value, exp_pos["lens-switch"])
        self.assertEqual(self.spec_det_sel.position.value, exp_pos["spec-det-selector"])
        self.assertEqual(self.ar_spec_sel.position.value, exp_pos["ar-spec-selector"])
Esempio n. 15
0
    def test_leech(self):
        """
        try acquisition with leech
        """
        # Create the streams and streamTree
        semsur = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam)
        sems = stream.SEMStream("test sem cl", self.sed, self.sed.data, self.ebeam)
        ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam)
        semars = stream.SEMARMDStream("test SEM/AR", [sems, ars])
        st = stream.StreamTree(streams=[semsur, semars])

        pcd = Fake0DDetector("test")
        pca = ProbeCurrentAcquirer(pcd)
        sems.leeches.append(pca)
        semsur.leeches.append(pca)

        # SEM survey settings are via the current hardware settings
        self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0]

        # SEM/AR settings are via the AR stream
        ars.roi.value = (0.1, 0.1, 0.8, 0.8)
        mx_brng = self.ccd.binning.range[1]
        binning = tuple(min(4, mx) for mx in mx_brng)  # try binning 4x4
        self.ccd.binning.value = binning
        self.ccd.exposureTime.value = 1  # s
        ars.repetition.value = (2, 3)
        num_ar = numpy.prod(ars.repetition.value)

        pca.period.value = 10  # Only at beginning and end

        est_time = acq.estimateTime(st.getProjections())

        # prepare callbacks
        self.start = None
        self.end = None
        self.updates = 0
        self.done = 0

        # Run acquisition
        start = time.time()
        f = acq.acquire(st.getProjections())
        f.add_update_callback(self.on_progress_update)
        f.add_done_callback(self.on_done)

        data, e = f.result()
        dur = time.time() - start
        self.assertGreaterEqual(dur, est_time / 2)  # Estimated time shouldn't be too small
        self.assertIsInstance(data[0], model.DataArray)
        self.assertIsNone(e)
        self.assertEqual(len(data), num_ar + 2)

        thumb = acq.computeThumbnail(st, f)
        self.assertIsInstance(thumb, model.DataArray)

        self.assertGreaterEqual(self.updates, 1)  # at least one update at end
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(not f.cancelled())

        time.sleep(0.1)
        self.assertEqual(self.done, 1)

        for da in data:
            pcmd = da.metadata[model.MD_EBEAM_CURRENT_TIME]
            self.assertEqual(len(pcmd), 2)
Esempio n. 16
0
    def on_acquisition_done(self, future):
        """ Callback called when the acquisition is finished (either successfully or cancelled) """
        self._set_fan(True)  # Turn the fan back on

        # bind button back to direct closure
        self.btn_cancel.Bind(wx.EVT_BUTTON, self.on_close)
        self._resume_settings()

        # re-enable estimation time updates
        view = self._tab_data_model.focussedView.value
        view.lastUpdate.subscribe(self.on_streams_changed)

        try:
            data, exp = 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

        # Handle the case acquisition failed "a bit"
        if exp:
            logging.error("Acquisition failed (after %d streams): %s",
                          len(data), exp)

        # 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_converter(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

        if exp:
            self.lbl_acqestimate.SetLabel("Acquisition failed (partially).")
        else:
            self.lbl_acqestimate.SetLabel("Acquisition completed.")
            # As the action is complete, rename "Cancel" to "Close"
            self.btn_cancel.SetLabel("Close")

        # Make sure the file is not overridden
        self.filename.value = self._get_default_filename()
        self.btn_secom_acquire.Enable()