예제 #1
0
    def test_context_manager(self):
        camera = Camera()

        with camera.recording():
            self.assertEqual(camera.state, 'recording')
            camera.grab()

        self.assertEqual(camera.state, 'standby')
예제 #2
0
    async def test_context_manager(self):
        camera = Camera()

        async with camera.recording():
            self.assertEqual(await camera.get_state(), 'recording')
            await camera.grab()

        self.assertEqual(await camera.get_state(), 'standby')
예제 #3
0
    def test_tomo_scanner(self):
        class Stage(object):
            def __init__(self):
                self.angles = []
                self.angle = 0.0 * q.deg

            def move(self, value):
                self.angle += value
                self.angles.append(self.angle)

        class PrepareChecker(object):
            def __init__(self):
                self.prepared = []

            def prepare_dark_scan(self):
                self.prepared.append('dark')

            def prepare_flat_scan(self):
                self.prepared.append('flat')

            def prepare_proj_scan(self):
                self.prepared.append('proj')

        camera = Camera()
        stage = Stage()
        checker = PrepareChecker()
        scanner = StepTomoScanner(camera, stage, checker.prepare_dark_scan,
                                  checker.prepare_flat_scan,
                                  checker.prepare_proj_scan)

        scanner.angle = 0.5 * q.deg

        darks, flats, projections = scanner.run().result()
        self.assertEqual(len(projections), len(stage.angles))
        compare(checker.prepared, ['dark', 'flat', 'proj'])
예제 #4
0
    def __init__(self,
                 tomo_axis=None,
                 flat_axis=None,
                 vertical_axis=None,
                 source=None):
        self.tomo_axis = tomo_axis
        self.flat_axis = flat_axis
        self.vertical_axis = vertical_axis
        self.source = source

        self._last_tomo_axis_position = None
        self._last_tomo_axis_velocity = None

        self._last_flat_axis_position = None
        self._last_flat_axis_velocity = None

        self._last_vertical_axis_position = None
        self._last_vertical_axis_velocity = None

        self._last_source_state = None

        Camera.__init__(self)
        self.exposure_time = 0.001 * q.s
예제 #5
0
    def connect_to_camera(self):
        """
        TODO: call you function connecting to camera
        :return: None
        """
        self.connect_to_camera_status.setText("CONNECTING...")
        self.connect_to_camera_status.setStyleSheet("color: orange")

        try:
            self.camera = UcaCamera('pcoclhs')
        except:
            self.on_camera_connect_failure()
        # try:
        #     self.camera = UcaCamera('pcoclhs')
        # except:
        #     self.on_camera_connect_failure()

        if self.camera is not None:
            self.on_camera_connect_success()
예제 #6
0
 def connect_to_dummy_camera(self):
     self.camera = DummyCamera()
     self.connect_to_camera_status.setText("CONNECTED")
     self.connect_to_camera_status.setStyleSheet("color: orange")
     self.camera_model_label.setText("Dummy camera")
     self.exposure_entry.setText("{:.02f}".format(
         self.camera.exposure_time.magnitude * 1000))
     self.fps_entry.setText("{:.02f}".format(int(1000.0 / self.exp_time)))
     self.roi_height_entry.setText("{}".format(
         self.camera.roi_height.magnitude))
     self.roi_width_entry.setText("{}".format(
         self.camera.roi_width.magnitude))
     self.roi_y0_entry.setText("{}".format(self.camera.roi_y0.magnitude))
     self.roi_x0_entry.setText("{}".format(self.camera.roi_x0.magnitude))
     self.live_preview_thread.camera = self.camera
     self.camera_connected_signal.emit(self.camera)
     self.live_on_button.setEnabled(True)
     self.live_off_button.setEnabled(True)
     self.save_one_image_button.setEnabled(True)
     self.camera.acquire_mode = None
예제 #7
0
class CameraControlsGroup(QGroupBox):
    """
    Camera controls
    """
    camera_connected_signal = pyqtSignal(object)

    def __init__(self, viewer, *args, **kwargs):
        # Timer - just as example
        super(CameraControlsGroup, self).__init__(*args, **kwargs)
        self.timer = QTimer()
        self.camera = None
        self.log = None

        # Buttons
        self.live_on_button = QPushButton("LIVE ON")
        self.live_on_button.clicked.connect(self.live_on_func)
        self.live_on_button.setEnabled(False)
        self.lv_duration = 0.0
        self.frames_in_last_lv_seq = 0

        self.live_on_button_stream2disk = QPushButton(
            "LIVE ON -> STREAM TO DISK")
        self.live_on_button_stream2disk.clicked.connect(
            self.live_on_func_stream2disk)
        self.live_on_button_stream2disk.setEnabled(False)
        self.live_on_stream_select_file_button = QPushButton(
            "Select directory to save streams")
        self.live_on_stream_select_file_button.setEnabled(False)
        self.live_on_stream_select_file_button.clicked.connect(
            self.live_on_stream2disk_prepare)
        self.lv_writer = None
        self.lv_dirwalker = None
        self.lv_experiment = None
        self.lv_acquisitions = None
        self.lv_stream2disk_on = False
        self.cons_viewer = None
        self.cons_writer = None
        self.fname = None

        self.live_off_button = QPushButton("LIVE OFF")
        self.live_off_button.setEnabled(False)
        self.live_off_button.clicked.connect(self.live_off_func)
        self.live_off_button.setEnabled(False)

        self.save_lv_sequence_button = QPushButton(
            "SAVE live-view sequence from Dimax")
        self.save_lv_sequence_button.clicked.connect(self.save_lv_seq)
        self.save_lv_sequence_button.setEnabled(False)
        self.frames_grabbed_so_far = 0

        self.abort_transfer_button = QPushButton("Abort transfer")
        self.abort_transfer_button.clicked.connect(self.abort_transfer_func)
        self.abort_transfer_button.setEnabled(False)
        self.abort_transfer = True

        self.lv_session_info = QLabel()

        #self.buffer_livev

        self.save_one_image_button = QPushButton("SAVE 1 image")
        self.save_one_image_button.clicked.connect(self.save_one_image)
        self.save_one_image_button.setEnabled(False)
        self.QFD = QFileDialog()
        self.nim = 0
        self.last_dir = "/data/image-"

        # Connect to camera
        self.connect_to_camera_button = QPushButton("Connect to camera")
        self.connect_to_camera_button.clicked.connect(self.connect_to_camera)
        self.connect_to_dummy_camera_button = QPushButton(
            "Connect to dummy camera")
        self.connect_to_dummy_camera_button.clicked.connect(
            self.connect_to_dummy_camera)
        self.connect_to_camera_status = QLabel()
        self.connect_to_camera_status.setText("NOT CONNECTED")
        self.connect_to_camera_status.setStyleSheet("color: red")
        self.camera_model_label = QLabel()
        # Camera object
        self.camera = None
        self.viewer = viewer
        self.live_on = False

        # external camera software switch
        self.ttl_scan = QCheckBox("External camera controls")
        self.ttl_scan.setChecked(False)

        # EXPOSURE
        self.exposure_label = QLabel()
        self.exposure_label.setText("EXPOSURE [msec]")
        self.exposure_entry = QLineEdit()
        self.exposure_units = QLabel()
        self.exposure_units.setText("msec")

        # FPS
        self.fps_label = QLabel()
        self.fps_label.setText("FRAMES PER SECOND")
        self.fps_entry = QLineEdit()

        self.fps_label_max = QLabel()
        self.fps_label_max.setText("Max fps, estimate")
        self.fps_label_max_val = QLabel()

        # DELAY
        self.delay_label = QLabel()
        self.delay_label.setText("Dead time [msec]")
        self.delay_entry = QLineEdit()
        self.delay_entry.setText("10")
        self.delay_units = QLabel()
        self.delay_units.setText("msec")

        # viewer limits
        self.viewer_lowlim_label = QLabel()
        self.viewer_lowlim_label.setText("Viewer low limit")
        self.viewer_lowlim_entry = QLineEdit()
        self.viewer_lowlim_entry.setText("20")
        self.viewer_highlim_label = QLabel()
        self.viewer_highlim_label.setText("Viewer high limit")
        self.viewer_highlim_entry = QLineEdit()
        self.viewer_highlim_entry.setText("50")

        # ROI
        # y0
        self.roi_y0_label = QLabel()
        self.roi_y0_label.setText("ROI first line")
        self.roi_y0_entry = QLineEdit()
        # height
        self.roi_height_label = QLabel()
        self.roi_height_label.setText("ROI height, lines")
        self.roi_height_entry = QLineEdit()
        # x0
        self.roi_x0_label = QLabel()
        self.roi_x0_label.setText("ROI first column")
        self.roi_x0_entry = QLineEdit()

        # width
        self.roi_width_label = QLabel()
        self.roi_width_label.setText("ROI width, columns")
        self.roi_width_entry = QLineEdit()
        # sensor_vertical_binning
        self.sensor_ver_bin_label = QLabel()
        self.sensor_ver_bin_label.setText("Vertical binning")
        self.sensor_ver_bin_entry = QLineEdit()
        self.sensor_ver_bin_entry.setText("1")
        # sensor_horizontal_binning
        self.sensor_hor_bin_label = QLabel()
        self.sensor_hor_bin_label.setText("Horizontal binning")
        self.sensor_hor_bin_entry = QLineEdit()
        self.sensor_hor_bin_entry.setText("1")

        # BUFFERED
        self.buffered_label = QLabel()
        self.buffered_label.setText("BUFFERED")
        self.buffered_entry = QComboBox()
        self.buffered_entry.addItems(["NO", "YES"])

        # N BUFFERS
        self.n_buffers_label = QLabel()
        self.n_buffers_label.setText("N BUFFERS")
        self.n_buffers_entry = QLineEdit()
        self.n_buffers_entry.setText("0")

        # TRIGGER
        self.trigger_label = QLabel()
        self.trigger_label.setText("TRIGGER")
        self.trigger_entry = QComboBox()
        self.trigger_entry.addItems(["AUTO", "SOFTWARE", "EXTERNAL"])

        # ACQUISITION MODE
        self.acq_mode_label = QLabel()
        self.acq_mode_label.setText("ACQUISITION MODE")
        self.acq_mode_entry = QComboBox()
        self.acq_mode_entry.addItems(["AUTO", "EXTERNAL"])
        self.acq_mode_entry.setEnabled(False)

        # STORAGE_MODE
        self.storage_mode_label = QLabel()
        self.storage_mode_label.setText("STORAGE MODE")
        self.storage_mode_entry = QComboBox()
        self.storage_mode_entry.addItems(["RECORDER", "FIFO"])
        #camera.storage_mode = camera.uca.enum_values.storage_mode.UCA_PCO_CAMERA_STORAGE_MODE_RECORDER
        #camera.storage_mode = camera.uca.enum_values.storage_mode.RECORDER
        #camera.storage_mode = camera.uca.enum_values.storage_mode.UCA_PCO_CAMERA_STORAGE_MODE_FIFO_BUFFER

        # RECORD MODE
        self.rec_mode_label = QLabel()
        self.rec_mode_label.setText("RECORD MODE")
        self.rec_mode_entry = QComboBox()
        self.rec_mode_entry.addItems(["RING BUFFER", "SEQUENCE"])

        # PIXELRATE line 6
        self.sensor_pix_rate_label = QLabel()
        self.sensor_pix_rate_label.setText("SENSOR PIXEL RATE, Hz")
        self.sensor_pix_rate_entry = QComboBox()

        # TIMESTAMP
        self.time_stamp = QCheckBox("Add timestamp to camera frames")
        self.time_stamp.setChecked(False)

        # Thread for live preview
        self.live_preview_thread = LivePreviewThread(viewer=self.viewer,
                                                     camera=self.camera)
        self.live_preview_thread.start()

        # Thread for live preview
        self.readout_thread = ReadoutThread(camera=self.camera)
        self.readout_thread.start()

        # signals
        self.ttl_scan.clicked.connect(self.extcamera_switched_func)
        self.exposure_entry.editingFinished.connect(self.relate_fps_to_exptime)
        self.roi_height_entry.editingFinished.connect(
            self.get_fps_max_estimate)
        # check that dead time is larger than readout time?
        self.readout_thread.readout_over_signal.connect(self.readout_over_func)
        self.time_stamp.stateChanged.connect(self.set_time_stamp)
        self.trigger_entry.currentIndexChanged.connect(
            self.restrict_params_depending_on_trigger)

        self.all_cam_params_correct = True
        self.set_layout()

    def constrain_buf_by_trig(self):
        if self.trigger_entry.currentText() == 'AUTO':
            tmp = self.buffered_entry.findText("NO")
            self.buffered_entry.setCurrentIndex(tmp)
        if self.trigger_entry.currentText() == 'SOFTWARE':
            tmp = self.buffered_entry.findText("NO")
            self.buffered_entry.setCurrentIndex(tmp)
            self.buffered_entry.setEnabled(False)
        if self.trigger_entry.currentText() == 'EXTERNAL':
            tmp = self.buffered_entry.findText("YES")
            self.buffered_entry.setCurrentIndex(tmp)
            self.buffered_entry.setEnabled(False)

    def set_layout(self):
        layout = QGridLayout()
        # Buttons on top
        # layout.addWidget(self.live_on_button, 0, 0, 1, 2)
        # layout.addWidget(self.live_off_button, 0, 2, 1, 2)
        layout.addWidget(self.live_on_button, 0, 0, 1, 2)
        layout.addWidget(self.live_off_button, 0, 2)
        layout.addWidget(self.save_one_image_button, 0, 3)
        layout.addWidget(self.live_on_button_stream2disk, 0, 4)
        layout.addWidget(self.live_on_stream_select_file_button, 0, 5)

        # Left column of controls
        layout.addWidget(self.connect_to_camera_button, 1, 0)
        layout.addWidget(self.connect_to_camera_status, 1, 1)
        #layout.addWidget(self.camera_model_label, 1, 2)
        layout.addWidget(self.connect_to_dummy_camera_button, 1, 2)
        layout.addWidget(self.ttl_scan, 1, 3)
        layout.addWidget(self.save_lv_sequence_button, 1, 4)
        layout.addWidget(self.abort_transfer_button, 1, 5)

        # viewer clims
        layout.addWidget(self.viewer_lowlim_label, 2, 0)
        layout.addWidget(self.viewer_lowlim_entry, 2, 1)
        layout.addWidget(self.viewer_highlim_label, 2, 2)
        layout.addWidget(self.viewer_highlim_entry, 2, 3)

        layout.addWidget(self.exposure_label, 3, 0)
        layout.addWidget(self.exposure_entry, 3, 1)
        #layout.addWidget(self.exposure_units, 2, 2)

        layout.addWidget(self.fps_label, 3, 2)
        layout.addWidget(self.fps_entry, 3, 3)
        layout.addWidget(self.fps_label_max, 4, 2)
        layout.addWidget(self.fps_label_max_val, 4, 3)

        layout.addWidget(self.delay_label, 4, 0)
        layout.addWidget(self.delay_entry, 4, 1)
        #layout.addWidget(self.delay_units, 3, 2)

        # Right column of controls
        layout.addWidget(self.buffered_label, 2, 4)
        layout.addWidget(self.buffered_entry, 2, 5)

        # layout.addWidget(self.buffer_location_label, 2, 4)
        # layout.addWidget(self.buffer_location_entry, 2, 5)

        layout.addWidget(self.n_buffers_label, 3, 4)
        layout.addWidget(self.n_buffers_entry, 3, 5)

        layout.addWidget(self.trigger_label, 4, 4)
        layout.addWidget(self.trigger_entry, 4, 5)

        # layout.addWidget(self.acq_mode_label, 5, 4)
        # layout.addWidget(self.acq_mode_entry, 5, 5)

        layout.addWidget(self.sensor_pix_rate_label, 5, 4)
        layout.addWidget(self.sensor_pix_rate_entry, 5, 5)

        layout.addWidget(self.time_stamp, 6, 4)

        #layout.addWidget(self.lv_session_info, 8, 4, 1, 2)

        for column in range(6):
            layout.setColumnStretch(column, 1)

        # ROI/bin group
        layout.addWidget(self.roi_y0_label, 5, 0)
        layout.addWidget(self.roi_y0_entry, 5, 1)
        layout.addWidget(self.roi_height_label, 6, 0)
        layout.addWidget(self.roi_height_entry, 6, 1)
        # layout.addWidget(self.sensor_ver_bin_label, 7, 0)
        # layout.addWidget(self.sensor_ver_bin_entry, 7, 1)
        layout.addWidget(self.roi_x0_label, 5, 2)
        layout.addWidget(self.roi_x0_entry, 5, 3)
        layout.addWidget(self.roi_width_label, 6, 2)
        layout.addWidget(self.roi_width_entry, 6, 3)
        # layout.addWidget(self.sensor_hor_bin_label, 7, 2)
        # layout.addWidget(self.sensor_hor_bin_entry, 7, 3)

        self.setLayout(layout)

    def connect_to_camera(self):
        """
        TODO: call you function connecting to camera
        :return: None
        """
        self.connect_to_camera_status.setText("CONNECTING...")
        self.connect_to_camera_status.setStyleSheet("color: orange")

        try:
            self.camera = UcaCamera('pcoclhs')
        except:
            self.on_camera_connect_failure()
        # try:
        #     self.camera = UcaCamera('pcoclhs')
        # except:
        #     self.on_camera_connect_failure()

        if self.camera is not None:
            self.on_camera_connect_success()

    def connect_to_dummy_camera(self):
        self.camera = DummyCamera()
        self.connect_to_camera_status.setText("CONNECTED")
        self.connect_to_camera_status.setStyleSheet("color: orange")
        self.camera_model_label.setText("Dummy camera")
        self.exposure_entry.setText("{:.02f}".format(
            self.camera.exposure_time.magnitude * 1000))
        self.fps_entry.setText("{:.02f}".format(int(1000.0 / self.exp_time)))
        self.roi_height_entry.setText("{}".format(
            self.camera.roi_height.magnitude))
        self.roi_width_entry.setText("{}".format(
            self.camera.roi_width.magnitude))
        self.roi_y0_entry.setText("{}".format(self.camera.roi_y0.magnitude))
        self.roi_x0_entry.setText("{}".format(self.camera.roi_x0.magnitude))
        self.live_preview_thread.camera = self.camera
        self.camera_connected_signal.emit(self.camera)
        self.live_on_button.setEnabled(True)
        self.live_off_button.setEnabled(True)
        self.save_one_image_button.setEnabled(True)
        self.camera.acquire_mode = None

    def on_camera_connect_success(self):
        """
        TODO: this function should be called from your camera connection software on successful connection
        :param camera: Camera object
        :return: None
        """
        self.connect_to_camera_status.setText("CONNECTED")
        self.connect_to_camera_status.setStyleSheet("color: green")
        self.connect_to_dummy_camera_button.setEnabled(False)
        self.connect_to_camera_button.setEnabled(False)
        self.ttl_scan.setEnabled(False)
        # identify model
        # Dimax must use internal buffer, 4000 only soft trigger
        if self.camera.sensor_width.magnitude == 2000:
            self.camera_model_label.setText("PCO Dimax")
            self.connect_to_camera_status.setText("CONNECTED to PCO Dimax")
            ####################################
            # !!!! can we hardcode it ???
            ####################################
            self.camera.storage_mode = self.camera.uca.enum_values.storage_mode.RECORDER
            self.camera.record_mode = self.camera.uca.enum_values.record_mode.RING_BUFFER
            ####
            tmp = self.buffered_entry.findText("NO")
            self.buffered_entry.setCurrentIndex(tmp)
            self.buffered_entry.setEnabled(False)
            self.n_buffers_entry.setEnabled(False)
        if self.camera.sensor_width.magnitude == 4008:
            self.camera_model_label.setText("PCO 4000")
            self.connect_to_camera_status.setText("CONNECTED to PCO 4000")
            self.trigger_entry.addItems(["SOFTWARE"])
            self.trigger_entry.setEnabled(False)
        if self.camera.sensor_width.magnitude == 2560:
            self.camera_model_label.setText("PCO Edge")
            self.connect_to_camera_status.setText("CONNECTED to PCO Edge")
            self.n_buffers_entry.setEnabled(True)
            self.live_on_button_stream2disk.setEnabled(True)
            self.live_on_stream_select_file_button.setEnabled(True)
        ####################################
        # Hardcoding automode for now
        ####################################
        if self.camera.acquire_mode != self.camera.uca.enum_values.acquire_mode.AUTO:
            self.camera.acquire_mode = self.camera.uca.enum_values.acquire_mode.AUTO
        self.camera.timestamp_mode = self.camera.uca.enum_values.timestamp_mode.NONE
        # set default values
        self.exposure_entry.setText("{:.02f}".format(
            self.camera.exposure_time.magnitude * 1000))
        self.fps_entry.setText("{}".format(int(1000.0 / self.exp_time)))
        self.roi_height_entry.setText("{}".format(
            self.camera.roi_height.magnitude))
        self.roi_height_label.setText("ROI height, lines (max. {})".format(
            self.camera.sensor_height.magnitude))
        self.roi_width_entry.setText("{}".format(
            self.camera.roi_width.magnitude))
        self.roi_width_label.setText("ROI width, columns (max. {})".format(
            self.camera.sensor_width.magnitude))
        self.roi_y0_entry.setText("{}".format(self.camera.roi_y0.magnitude))
        self.roi_x0_entry.setText("{}".format(self.camera.roi_x0.magnitude))
        self.sensor_pix_rate_entry.addItems(
            [str(i) for i in self.camera.sensor_pixelrates])
        tmp = self.sensor_pix_rate_entry.findText(
            str(self.camera.sensor_pixelrate))
        self.sensor_pix_rate_entry.setCurrentIndex(tmp)
        #sensor_vertical_binning
        # sensor_horizontal_vertical_binning
        self.live_preview_thread.camera = self.camera
        self.readout_thread.camera = self.camera
        self.camera_connected_signal.emit(self.camera)
        self.live_on_button.setEnabled(True)
        self.live_off_button.setEnabled(True)
        self.save_one_image_button.setEnabled(True)
        #had to add this in order to avoid that signals
        #coming to early can break the matplotlib window
        self.live_on_func()
        sleep(1)
        self.live_off_func()
        self.restrict_params_depending_on_trigger()
        self.get_fps_max_estimate()

    def on_camera_connect_failure(self):
        """
        TODO: this function should be called from your camera connection software on connection failure
            or on timeout
        :return: None
        """
        self.connect_to_camera_status.setText("CONNECTION FAILED")
        self.connect_to_camera_status.setStyleSheet("color: red")
        self.camera = None
        self.camera_model_label.setText("")

    def set_camera_params(self):
        self.log.info("Setting camera parameters")
        if self.camera_model_label.text() == 'Dummy camera':
            return -1
        try:
            if self.camera.state == 'recording':
                self.camera.stop_recording()
            self.camera.exposure_time = self.exp_time * q.msec
            if self.camera_model_label.text() == "PCO Dimax":
                self.camera.frame_rate = self.fps * q.hertz
            else:
                self.camera.sensor_pixelrate = int(
                    self.sensor_pix_rate_entry.currentText())
            self.camera.buffered = self.buffered
            if self.camera.buffered:
                self.camera.num_buffers = self.buffnum
            self.set_time_stamp()
            self.setROI()
        except:
            tmp = "Can not set camera parameters"
            self.log.error(tmp)
            error_message(tmp)
            return True
        else:
            return False

    def set_time_stamp(self):
        if self.time_stamp.isChecked():
            self.camera.timestamp_mode = self.camera.uca.enum_values.timestamp_mode.BINARY
        else:
            self.camera.timestamp_mode = self.camera.uca.enum_values.timestamp_mode.NONE

    def setROI(self):
        try:
            self.camera.roi_x0 = self.roi_x0 * q.pixels
            self.camera.roi_y0 = self.roi_y0 * q.pixels
            self.camera.roi_width = self.roi_width * q.pixels
            self.camera.roi_height = self.roi_height * q.pixels
        except:
            error_message(
                "ROI is not correctly defined for the sensor, check multipliers and centering"
            )

    def live_on_func(self):
        self.log.info("Live view on with auto trigger")
        self.ena_disa_buttons(False)
        if self.camera.state == "recording":
            self.camera.stop_recording()
        if self.camera_model_label.text() == 'Dummy camera':
            pass
        else:
            if self.camera.trigger_source != self.camera.trigger_sources.AUTO:
                self.camera.trigger_source = self.camera.trigger_sources.AUTO
        self.set_camera_params()
        self.camera.start_recording()
        self.live_preview_thread.live_on = True
        self.lv_duration = time.time()

    def live_on_func_ext_trig(self):
        self.log.info("Live view on with external trigger")
        self.ena_disa_buttons(False)
        if self.camera.state == "recording":
            self.camera.stop_recording()
        if self.camera.trigger_source != self.camera.trigger_sources.EXTERNAL:
            self.camera.trigger_source = self.camera.trigger_sources.EXTERNAL
        self.set_camera_params()
        self.camera.start_recording()
        #self.live_preview_thread.live_on = True #not working with external triggers
        self.lv_duration = time.time()

    def live_on_stream2disk_prepare(self):
        self.fname, fext = self.QFD.getSaveFileName(self, 'Select directory',
                                                    self.last_dir,
                                                    "Image Files (*.tif)")
        self.lv_dirwalker = DirectoryWalker(root=os.path.dirname(self.fname),
                                            dsetname="frames_{:>02}.tif",
                                            bytes_per_file=2**37)
        self.lv_acquisitions = [Acquisition("Radios", self.acq_lv_stream2disk)]
        self.lv_experiment = Experiment(acquisitions=self.lv_acquisitions,
                                        walker=self.lv_dirwalker,
                                        separate_scans=True,
                                        name_fmt="live_view_seq_{:>03}")
        self.cons_writer = ImageWriter(self.lv_acquisitions,
                                       self.lv_dirwalker,
                                       async=True)
        self.cons_viewer = Consumer(self.lv_acquisitions, self.viewer)

    def acq_lv_stream2disk(self):
        self.log.info("Streaming lv sequence to disk")
        self.ena_disa_buttons(False)
        if self.camera.state == "recording":
            self.camera.stop_recording()
        if self.camera.trigger_source != self.camera.trigger_sources.AUTO:
            self.camera.trigger_source = self.camera.trigger_sources.AUTO
        self.set_camera_params()
        try:
            self.camera.start_recording()
            while self.lv_stream2disk_on:
                yield self.camera.grab()
        except Exception as exp:
            self.log.error(exp)

    def live_on_func_stream2disk(self):
        if self.fname == None:
            error_message("Select the filename first")
            return
        self.lv_stream2disk_on = True
        self.lv_experiment.run()

    def live_off_func(self):
        self.log.info("Live off func called")
        self.live_preview_thread.live_on = False
        self.lv_stream2disk_on = False
        self.ena_disa_buttons(True)
        try:
            self.camera.stop_recording()
        except Exception as exp:
            self.log.error("Cannot stop recording to stop the live view")
            self.log.error(exp)
            # if self.camera_model_label.text() != 'Dummy camera':
            #    error_message("Cannot stop recording")
        self.lv_duration = time.time() - self.lv_duration
        self.frames_in_last_lv_seq = 0.0
        self.live_off_button.setEnabled(False)
        self.live_on_button.setEnabled(True)
        if self.camera_model_label.text() == 'PCO Dimax':  # or self.buffered:
            self.save_lv_sequence_button.setEnabled(True)
            self.frames_in_last_lv_seq = self.camera.recorded_frames.magnitude
            self.setTitle(
                "Camera controls. Status: recorded {0} frames in {1:.03f} seconds"
                .format(self.frames_in_last_lv_seq, self.lv_duration))
        self.log.info("Live view stopped")

    def save_lv_seq(self):
        self.abort_transfer_button.setEnabled(True)
        self.save_lv_sequence_button.setEnabled(False)
        self.live_on_button.setEnabled(False)
        self.save_one_image_button.setEnabled(False)
        # Get file name
        f, fext = self.QFD.getSaveFileName(self, 'Select dir and enter prefix',
                                           self.last_dir,
                                           "Image Files (*.tif)")
        if f == self.last_dir:
            f += "/im-seq-00"
        self.last_dir = os.path.dirname(f)

        # Start readout
        self.readout_thread.filename = f + '.tif'
        self.readout_thread.readout_on = True

    def abort_transfer_func(self):
        ## Readuot Thread
        self.readout_thread.abort_transfer = True
        self.abort_transfer_button.setEnabled(False)

    def readout_over_func(self, val):
        self.live_on_button.setEnabled(val)
        self.save_one_image_button.setEnabled(val)
        self.abort_transfer_button.setEnabled(False)

    def save_one_image(self):
        self.save_one_image_button.setEnabled(False)
        f, fext = self.QFD.getSaveFileName(self, 'Save image', self.last_dir,
                                           "Image Files (*.tif)")
        if f == self.last_dir:
            fname = os.path.join(f, "image-{:>04}.tif".format(self.nim))
            self.nim += 1
        else:
            fname = f + '.tif'
        self.last_dir = os.path.dirname(fname)
        tmp = False
        if self.live_preview_thread.live_on == True:
            self.live_off_func()
            tmp = True
        if self.camera_model_label.text() != 'Dummy camera':
            if self.camera.state == 'recording':
                self.camera.stop_recording()
            self.camera['trigger_source'].stash().join()
            self.camera.trigger_source = self.camera.trigger_sources.SOFTWARE
        self.set_camera_params()
        try:
            if self.camera_model_label.text() != 'Dummy camera':
                with self.camera.recording():
                    self.camera.trigger()
                    im = self.camera.grab()
            else:
                im = self.camera.grab()
        finally:
            write_tiff(fname, im)
            if self.camera_model_label.text() != 'Dummy camera':
                self.camera['trigger_source'].restore().join()
            self.save_one_image_button.setEnabled(True)
        if tmp == True:
            self.live_on_func()

    def restrict_params_depending_on_trigger(self):
        self.delay_entry.setText('0')
        self.delay_entry.setEnabled(False)
        if self.trigger_entry.currentText() == 'SOFTWARE':
            tmp = self.buffered_entry.findText("NO")
            self.buffered_entry.setCurrentIndex(tmp)
            self.buffered_entry.setEnabled(False)
            self.n_buffers_entry.setEnabled(False)
        # delays only applicable in case of external trigger
        if self.trigger_entry.currentText() == 'EXTERNAL':
            if self.camera_model_label.text() == 'PCO Dimax':
                self.delay_entry.setText('1')
                self.buffered_entry.setEnabled(False)
                self.n_buffers_entry.setEnabled(False)
            if self.camera_model_label.text() == 'PCO Edge':
                self.delay_entry.setText('{0:d}'.format(
                    1000 / self.get_fps_max_estimate()))
                self.buffered_entry.setEnabled(True)
                self.n_buffers_entry.setEnabled(True)
            self.delay_entry.setEnabled(True)

    def ena_disa_buttons(self, val):
        self.live_on_button_stream2disk.setEnabled(val)
        self.live_on_stream_select_file_button.setEnabled(val)
        self.live_on_button.setEnabled(val)
        if self.camera_model_label.text() == 'PCO Dimax':
            self.save_lv_sequence_button.setEnabled(val)
        self.live_off_button.setEnabled(not val)

        # getters/setters
    @property
    def exp_time(self):
        try:
            x = float(self.exposure_entry.text())
        except ValueError:
            error_message("{:}".format(
                "Exp. time must be a positive number. Setting to default"))
            x = 13
            self.all_cam_params_correct = False
        if x < 0:
            error_message(
                "{:}".format("Exp. time must be positive. Setting to default"))
            x = 13
            self.exposure_entry.setText('13')
            self.all_cam_params_correct = False
        if self.camera_model_label.text() == 'PCO Dimax' and (x > 40):
            error_message("{:}".format("Max exp. time for Dimax is 40 msec"))
            self.all_cam_params_correct = False
            x = 39.9999
            self.exposure_entry.setText('39.9999')
        if self.camera_model_label.text() == 'PCO Edge' and (x > 2000):
            error_message("{:}".format("Max exp. time for Edge is 2 sec"))
            x = 1999.9
            self.exposure_entry.setText('1999.9')
            self.all_cam_params_correct = False
        return x

    def relate_fps_to_exptime(self):
        if self.trig_mode == "EXTERNAL":
            if self.camera_model_label.text() == 'PCO Dimax':
                x = int(1000.0 / self.exp_time)
            else:
                x = int(1000.0 / (self.exp_time + self.dead_time))
        else:
            x = int(1000.0 / self.exp_time)
        self.fps_entry.setText("{:.02f}".format(x))
        return x

    def get_fps_max_estimate(self):
        x = 0
        if self.camera_model_label.text() == 'PCO Dimax':
            x = 2200 * 2000 / self.roi_height
        if self.camera_model_label.text() == 'PCO Edge':
            x = 100 * 2160 / self.roi_height
        if self.camera_model_label.text() == 'PCO 4000':
            x = 4
        x = int(x)
        self.fps_label_max_val.setText(str(x))
        return x

    @property
    def fps(self):
        try:
            x = float(self.fps_entry.text())
        except ValueError:
            warning_message("{:}".format(
                "FPS a positive number. Setting FPS based on exp. time"))
            x = self.relate_fps_to_exptime()
        if x < 0:
            error_message("{:}".format("FPS must be positive"))
            self.all_cam_params_correct = False
        if self.camera_model_label.text() == 'PCO Dimax':
            if x < 25:
                warning_message(
                    "{:}".format("Dimax FPS must be greater than 25"))
                x = 25
            if self.trig_mode == "EXTERNAL" and \
                    int(x) < int(1000.0 / (self.exp_time + self.dead_time)):
                warning_message("{:}".format(
                    "Dimax FPS must be greater than frequency of external triggers"
                ))
                x = int(1000.0 / self.exp_time)
        # if self.camera_model_label.text() == 'PCO Edge' and (x > 100):
        #     error_message("{:}".format("PCO Edge max FPS is 100"))
        #     self.all_cam_params_correct = False
        # if int(x) < int(1000.0 / (self.exp_time + self.dead_time)): #because of round of errors
        #     #warning_message("FPS [Hz] cannot exceed 1/exp.time[s]; setting fps=1/exp.time")
        #     self.relate_fps_to_exptime()
        elif self.trig_mode == "EXTERNAL":
            x = self.relate_fps_to_exptime()
        self.fps_entry.setText("{:.02f}".format(x))
        return x

    @property
    def dead_time(self):
        try:
            x = float(self.delay_entry.text())
        except ValueError:
            warning_message(
                "{:}".format("Dead time must be a non-negative number"))
            x = 0
            self.delay_entry.setText('0')
            self.all_cam_params_correct = False
        if x < 0:
            warning_message(
                "{:}".format("Dead time must be a non-negative number"))
            x = 0
            self.delay_entry.setText('0')
            self.all_cam_params_correct = False
        return x

    @property
    def roi_height(self):
        try:
            h = int(self.roi_height_entry.text())
        except ValueError:
            error_message(
                "ROI height must be  positive integer number smaller then {}".
                format(self.camera.sensor_height.magnitude))
        if self.camera_model_label.text() == 'PCO Dimax':
            h = int(h / 4) * 4
            if h > 2000:
                h = 2000
            self.roi_height_entry.setText(str(h))
            return h
        if self.camera_model_label.text() == 'PCO Edge':
            h = int(h / 2) * 2
            if h > 2160:
                h = 2160
            self.roi_y0_entry.setText(str(1080 - int(h / 2)))
            self.roi_height_entry.setText(str(h))
        return h

    @property
    def roi_y0(self):
        try:
            h = int(self.roi_y0_entry.text())
        except ValueError:
            if self.camera_model_label.text() == 'PCO Dimax':
                error_message(
                    "ROI height must be positive integer number divisible by 4 and smaller then {:}"
                    .format(996))
            else:
                error_message(
                    "ROI height must be positive integer number smaller then {:}"
                    .format(self.camera.sensor_height.magnitude))
        if self.camera_model_label.text() == 'PCO Dimax':
            h = 1000 - self.roi_height / 2
            self.roi_y0_entry.setText(str(h))
            return h
        else:
            return h

    @property
    def roi_x0(self):
        try:
            h = int(self.roi_x0_entry.text())
        except ValueError:
            if self.camera_model_label.text() == 'PCO Dimax':
                error_message(
                    "ROI height must be positive integer number divisible by 4 and smaller then {:}"
                    .format(996))
            else:
                error_message(
                    "ROI height must be positive integer number smaller then {:}"
                    .format(self.camera.sensor_height.magnitude))
        if self.camera_model_label.text() == 'PCO Dimax':
            h = 1000 - self.roi_width / 2
            self.roi_x0_entry.setText(str(h))
            return h
        else:
            return h

    @property
    def roi_width(self):
        try:
            h = int(self.roi_width_entry.text())
        except ValueError:
            error_message(
                "ROI height must be  positive integer number smaller then {}".
                format(self.camera.sensor_height.magnitude))
        if self.camera_model_label.text() == 'PCO Dimax':
            h = int(h / 4) * 4
            if h > 2000:
                h = 2000
            self.roi_width_entry.setText(str(h))
            return h
        else:
            return h

    @property
    def trig_mode(self):
        try:
            return self.trigger_entry.currentText()
        except ValueError:
            return None

    @property
    def acq_mode(self):
        try:
            return self.acq_mode_entry.currentText()
        except ValueError:
            return None

    @property
    def buffered(self):
        if self.camera_model_label == "PCO Dimax":
            return False
        try:
            if self.buffered_entry.currentText() == "YES":
                return True
            else:
                return False
        except ValueError:
            return None

    @property
    def buffnum(self):
        try:
            return int(self.n_buffers_entry.text())
        except ValueError:
            return None

    @property
    def pix_rate(self):
        try:
            return int(self.sensor_pix_rate_entry.currentText())
        except:
            warning_message('Can not get read-out rate')

    def extcamera_switched_func(self):
        if self.ttl_scan.isChecked():
            self.live_on_button.setEnabled(False)
            self.live_off_button.setEnabled(False)
            self.save_one_image_button.setEnabled(False)
        else:
            self.live_on_button.setEnabled(True)
            self.live_off_button.setEnabled(True)
            self.save_one_image_button.setEnabled(True)
예제 #8
0
 def setUp(self):
     self.seq = list(range(10))
     self.camera = Camera()
     self.linear_motor = LinearMotor()
     self.linear_motor2 = LinearMotor()
     self.rotation_motor = RotationMotor()
예제 #9
0
 def __init__(self, camera=None, magnification=None):
     self._camera = Camera() if camera is None else camera
     self._magnification = 3 if magnification is None else magnification
     super(Detector, self).__init__()
예제 #10
0
 def setUp(self):
     self.motor = LinearMotor()
     self.camera = Camera()
     self.shutter = Shutter()
예제 #11
0
 def setUp(self):
     super(TestDummyCamera, self).setUp()
     self.background = np.ones((256, 256), dtype=np.uint16)
     self.camera = Camera(background=self.background)
예제 #12
0
 async def test_simulate(self):
     self.assertTrue(np.any(self.background - await self.camera.grab()))
     camera = Camera(background=self.background, simulate=False)
     np.testing.assert_equal(self.background, await camera.grab())
예제 #13
0
class TestDummyCamera(TestCase):

    def setUp(self):
        super(TestDummyCamera, self).setUp()
        self.camera = Camera()

    def test_grab(self):
        frame = self.camera.grab()
        self.assertIsNotNone(frame)

    def test_grab_async(self):
        frame = self.camera.grab_async().result()
        self.assertIsNotNone(frame)

    def test_trigger_source(self):
        self.camera.trigger_source = self.camera.trigger_sources.EXTERNAL
        self.assertEqual(self.camera.trigger_source, 'EXTERNAL')

    def test_roi(self):
        self.roi_x0 = self.roi_y0 = self.roi_width = self.roi_height = 10 * q.dimensionless
        self.assertEqual(self.roi_x0, 10 * q.dimensionless)
        self.assertEqual(self.roi_y0, 10 * q.dimensionless)
        self.assertEqual(self.roi_width, 10 * q.dimensionless)
        self.assertEqual(self.roi_height, 10 * q.dimensionless)

    def test_has_sensor_dims(self):
        self.assertTrue(hasattr(self.camera, "sensor_pixel_width"))
        self.assertTrue(hasattr(self.camera, "sensor_pixel_height"))

    def test_buffered_camera(self):
        camera = BufferedCamera()
        for i, item in enumerate(camera.readout_buffer()):
            pass
        self.assertEqual(i, 2)

    def test_context_manager(self):
        camera = Camera()

        with camera.recording():
            self.assertEqual(camera.state, 'recording')
            camera.grab()

        self.assertEqual(camera.state, 'standby')

    def test_stream(self):
        @coroutine
        def check():
            while True:
                yield
                check.ok = True
                self.camera.stop_recording()
        check.ok = False

        self.camera.stream(check()).join()
        self.assertTrue(check.ok)

    def test_grab_convert(self):
        def grab():
            return np.mgrid[:5, :5][1]

        self.camera._grab_real = grab
        self.camera.convert = np.fliplr
        image = self.camera.grab()
        np.testing.assert_equal(image, grab()[:, ::-1])
예제 #14
0
 def setUp(self):
     super(TestDummyCamera, self).setUp()
     self.camera = Camera()
예제 #15
0
    camera.start_recording()

    for i in xrange(num_frames):
        yield camera.grab()


def reconstruct_from(camera):
    pm = PluginManager()

    fft = pm.get_task('fft', dimensions=1)
    ifft = pm.get_task('ifft', dimensions=1)
    fltr = pm.get_task('filter')
    bp = pm.get_task('backproject')
    writer = pm.get_task('write')

    graph = Ufo.TaskGraph()
    graph.connect_nodes(fft, fltr)
    graph.connect_nodes(fltr, ifft)
    graph.connect_nodes(ifft, bp)
    graph.connect_nodes(bp, writer)

    with InjectProcess(graph) as process:
        for frame in acquire(camera, 10):
            process.insert(frame)


if __name__ == '__main__':
    camera = Camera()
    camera.frame_rate = 10 * q.count / q.s
    reconstruct_from(camera)
예제 #16
0
class TestDummyCamera(TestCase):
    def setUp(self):
        super(TestDummyCamera, self).setUp()
        self.background = np.ones((256, 256), dtype=np.uint16)
        self.camera = Camera(background=self.background)

    async def test_grab(self):
        frame = await self.camera.grab()
        self.assertIsNotNone(frame)

    def test_trigger_source(self):
        self.camera.trigger_source = self.camera.trigger_sources.EXTERNAL
        self.assertEqual(self.camera.trigger_source, 'EXTERNAL')

    def test_roi(self):
        self.roi_x0 = self.roi_y0 = self.roi_width = self.roi_height = 10 * q.dimensionless
        self.assertEqual(self.roi_x0, 10 * q.dimensionless)
        self.assertEqual(self.roi_y0, 10 * q.dimensionless)
        self.assertEqual(self.roi_width, 10 * q.dimensionless)
        self.assertEqual(self.roi_height, 10 * q.dimensionless)

    def test_has_sensor_dims(self):
        self.assertTrue(hasattr(self.camera, "sensor_pixel_width"))
        self.assertTrue(hasattr(self.camera, "sensor_pixel_height"))

    async def test_buffered_camera(self):
        camera = BufferedCamera()
        i = 0
        async for item in camera.readout_buffer():
            i += 1
        self.assertEqual(i, 3)

    async def test_context_manager(self):
        camera = Camera()

        async with camera.recording():
            self.assertEqual(await camera.get_state(), 'recording')
            await camera.grab()

        self.assertEqual(await camera.get_state(), 'standby')

    async def test_stream(self):
        async def check(producer):
            async for image in producer:
                check.ok = True
                await self.camera.stop_recording()
                break

        check.ok = False

        await check(self.camera.stream())
        self.assertTrue(check.ok)

    async def test_grab_convert(self):
        async def grab():
            return np.mgrid[:5, :5][1]

        self.camera._grab_real = grab
        self.camera.convert = np.fliplr
        image = await self.camera.grab()
        np.testing.assert_equal(image, (await grab())[:, ::-1])

    async def test_simulate(self):
        self.assertTrue(np.any(self.background - await self.camera.grab()))
        camera = Camera(background=self.background, simulate=False)
        np.testing.assert_equal(self.background, await camera.grab())
예제 #17
0
 async def test_frames(self):
     acc = Accumulate()
     await acc(frames(5, Camera()))
     assert len(acc.items) == 5