Source code for mesoSPIM.src.mesoSPIM_Camera

'''
mesoSPIM Camera class, intended to run in its own thread
'''

import time
import numpy as np
import logging
logger = logging.getLogger(__name__)

from PyQt5 import QtCore, QtWidgets, QtGui
'''
try:
    from .devices.cameras.hamamatsu import hamamatsu_camera as cam
except:
    logger.info('Error: Hamamatsu camera could not be imported')
'''

from .utils.acquisitions import AcquisitionList, Acquisition
from .utils.utility_functions import log_cpu_core


[docs] class mesoSPIM_Camera(QtCore.QObject): '''Top-level class for all cameras''' sig_camera_frame = QtCore.pyqtSignal() sig_write_images = QtCore.pyqtSignal(Acquisition, AcquisitionList) sig_finished = QtCore.pyqtSignal() sig_update_gui_from_state = QtCore.pyqtSignal() sig_status_message = QtCore.pyqtSignal(str) def __init__(self, parent, frame_queue, frame_queue_display): super().__init__() self.parent = parent # a mesoSPIM_Core() object self.cfg = parent.cfg self.frame_queue = frame_queue self.frame_queue_display = frame_queue_display self.state = self.parent.state # a mesoSPIM_StateSingleton() object #self.image_writer = mesoSPIM_ImageWriter(self) self.stopflag = False self.x_pixels = self.cfg.camera_parameters['x_pixels'] self.y_pixels = self.cfg.camera_parameters['y_pixels'] self.x_pixel_size_in_microns = self.cfg.camera_parameters['x_pixel_size_in_microns'] self.y_pixel_size_in_microns = self.cfg.camera_parameters['y_pixel_size_in_microns'] self.binning_string = self.cfg.camera_parameters['binning'] # Should return a string in the form '2x4' self.x_binning = int(self.binning_string[0]) self.y_binning = int(self.binning_string[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) self.camera_line_interval = self.cfg.startup['camera_line_interval'] self.camera_exposure_time = self.cfg.startup['camera_exposure_time'] self.camera_display_live_subsampling = self.cfg.startup['camera_display_live_subsampling'] self.camera_display_acquisition_subsampling = self.cfg.startup['camera_display_acquisition_subsampling'] if 'camera_display_temporal_subsampling' in self.cfg.startup.keys(): self.camera_display_temporal_subsampling = self.cfg.startup['camera_display_temporal_subsampling'] else: self.camera_display_temporal_subsampling = 2 logger.debug(f'Camera display temporal subsampling factor: {self.camera_display_temporal_subsampling}') ''' Wiring signals ''' self.parent.sig_state_request.connect(self.state_request_handler) # from mesoSPIM_Core() to mesoSPIM_Camera() self.parent.sig_prepare_image_series.connect(self.prepare_image_series, type=QtCore.Qt.BlockingQueuedConnection) self.parent.sig_add_images_to_image_series.connect(self.add_images_to_series, type=QtCore.Qt.QueuedConnection) # self.parent.sig_add_images_to_image_series_and_wait_until_done.connect(self.add_images_to_series, type=QtCore.Qt.BlockingQueuedConnection) #self.parent.sig_write_metadata.connect(self.image_writer.write_metadata, type=QtCore.Qt.BlockingQueuedConnection) self.parent.sig_prepare_live.connect(self.prepare_live, type=QtCore.Qt.BlockingQueuedConnection) self.parent.sig_get_live_image.connect(self.get_live_image) self.parent.sig_get_snap_image.connect(self.snap_image) self.parent.sig_end_live.connect(self.end_live, type=QtCore.Qt.BlockingQueuedConnection) ''' Set up the actual camera ''' if self.cfg.camera == 'HamamatsuOrca': self.camera = mesoSPIM_HamamatsuCamera(self) elif self.cfg.camera == 'Photometrics': self.camera = mesoSPIM_PhotometricsCamera(self) elif self.cfg.camera == 'PCO': self.camera = mesoSPIM_PCOCamera(self) elif self.cfg.camera == 'DemoCamera': self.camera = mesoSPIM_DemoCamera(self) self.camera.open_camera() logger.info('Camera initialized') def __del__(self): try: self.camera.close_camera() except: pass @QtCore.pyqtSlot(dict) def state_request_handler(self, dict): '''The request handling is done with exec() to write fewer lines of code. ''' for key, value in zip(dict.keys(), dict.values()): if key in ('camera_exposure_time', 'camera_line_interval', 'state', 'camera_display_live_subsampling', 'camera_display_acquisition_subsampling', 'camera_binning'): exec('self.set_'+key+'(value)') elif key == 'state': if value == 'live': logger.debug('Thread name during live: '+ (QtCore.QThread.currentThread().objectName()))
[docs] def set_state(self, value): pass
@QtCore.pyqtSlot() def stop(self): ''' Stops acquisition ''' self.stopflag = True
[docs] def set_camera_exposure_time(self, time): ''' Sets the exposure time in seconds Args: time (float): exposure time to set ''' self.camera.set_exposure_time(time) self.camera_exposure_time = time self.state['camera_exposure_time'] = time
#self.sig_update_gui_from_state.emit()
[docs] def set_camera_line_interval(self, time): ''' Sets the line interval in seconds Args: time (float): interval time to set ''' self.camera.set_line_interval(time) self.camera_line_interval = time self.state['camera_line_interval'] = time
#self.sig_update_gui_from_state.emit()
[docs] def set_camera_display_live_subsampling(self, factor): self.camera_display_live_subsampling = factor self.state['camera_display_live_subsampling'] = factor
[docs] def set_camera_display_acquisition_subsampling(self, factor): self.camera_display_acquisition_subsampling = factor self.state['camera_display_acquisition_subsampling'] = factor
[docs] def set_camera_binning(self, value): logger.info('Setting camera binning: '+value) self.camera.set_binning(value) self.state['camera_binning'] = value
@QtCore.pyqtSlot(Acquisition, AcquisitionList) def prepare_image_series(self, acq, acq_list): ''' Row is a row in a AcquisitionList ''' logger.info('Camera: Preparing Image Series') self.stopflag = False #self.image_writer.prepare_acquisition(acq, acq_list) self.max_frame = acq.get_image_count() self.processing_options_string = acq['processing'] self.camera.initialize_image_series() self.cur_image = 0 logger.info(f'Camera: Finished Preparing Image Series') self.start_time = time.time() @QtCore.pyqtSlot(Acquisition, AcquisitionList) def add_images_to_series(self, acq, acq_list): if self.cur_image == 0: logger.debug('Thread name during add images: '+ QtCore.QThread.currentThread().objectName()) if self.stopflag is False: if self.cur_image < self.max_frame: logger.debug(f'Adding images to series') log_cpu_core(logger, msg='add_images_to_series()') images = self.camera.get_images_in_series() logger.debug(f'Got {len(images)} images') self.frame_queue.extend(images) # push the list of images into queue # show an image every other timepoint to prevent GUI freezing in long acquisitions if self.cur_image % self.camera_display_temporal_subsampling == 0: self.frame_queue_display.append(np.rot90(images[0])) # push the first image into the display queue self.sig_camera_frame.emit() # signal the GUI to update the display # tell the image writer to write the images in queue self.sig_write_images.emit(acq, acq_list) self.cur_image += len(images) @QtCore.pyqtSlot(Acquisition, AcquisitionList) def end_image_series(self, acq, acq_list): logger.debug("end_image_series() started") try: self.camera.close_image_series() logger.debug("self.camera.close_image_series()") except Exception as e: logger.error(f'Camera: Image Series could not be closed: {e}') #self.image_writer.end_acquisition(acq, acq_list) self.end_time = time.time() framerate = (self.cur_image + 1)/(self.end_time - self.start_time) logger.info(f'Camera: Framerate: {framerate:.2f}') self.sig_finished.emit() @QtCore.pyqtSlot(bool) def snap_image(self, write_flag=True): """"Snap an image and display it""" log_cpu_core(logger, msg='snap_image()') image = np.rot90(self.camera.get_image()) self.frame_queue_display.append(image) # push the first image into the display queue logger.info(f"Image appended to display queue: len(frame_queue_display)={len(self.frame_queue_display)}") self.sig_camera_frame.emit() # signal the GUI to update the display if write_flag: self.parent.image_writer.write_snap_image(image) # Dangerous, not thread safe! @QtCore.pyqtSlot() def prepare_live(self): self.camera.initialize_live_mode() self.live_image_count = 0 self.start_time = time.time() logger.info('Camera: Preparing Live Mode') @QtCore.pyqtSlot() def get_live_image(self): images = self.camera.get_live_image() log_cpu_core(logger, msg='get_live_image()') for image in images: self.frame_queue_display.append(np.rot90(image)) # push the first image into the display queue self.sig_camera_frame.emit() # signal the GUI to update the display self.live_image_count += 1 #self.sig_camera_status.emit(str(self.live_image_count)) @QtCore.pyqtSlot() def end_live(self): self.camera.close_live_mode() self.end_time = time.time() framerate = (self.live_image_count + 1)/(self.end_time - self.start_time) logger.info(f'Camera: Finished Live Mode: Framerate: {framerate:.2f}')
[docs] class mesoSPIM_GenericCamera(QtCore.QObject): ''' Generic mesoSPIM camera class meant for subclassing.''' def __init__(self, parent): super().__init__() self.parent = parent self.cfg = parent.cfg self.state = self.parent.state # the mesoSPIM_StateSingleton() object self.stopflag = False self.x_pixels = self.cfg.camera_parameters['x_pixels'] self.y_pixels = self.cfg.camera_parameters['y_pixels'] self.x_pixel_size_in_microns = self.cfg.camera_parameters['x_pixel_size_in_microns'] self.y_pixel_size_in_microns = self.cfg.camera_parameters['y_pixel_size_in_microns'] self.binning_string = self.cfg.camera_parameters['binning'] # Should return a string in the form '2x4' self.x_binning = int(self.binning_string[0]) self.y_binning = int(self.binning_string[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) self.camera_line_interval = self.cfg.startup['camera_line_interval'] self.camera_exposure_time = self.cfg.startup['camera_exposure_time']
[docs] def open_camera(self): pass
[docs] def close_camera(self): pass
[docs] def set_exposure_time(self, time): self.camera_exposure_time = time
[docs] def set_line_interval(self, time): pass
[docs] def set_binning(self, binning_string): self.x_binning = int(binning_string[0]) self.y_binning = int(binning_string[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) self.state['camera_binning'] = str(self.x_binning)+'x'+str(self.y_binning)
[docs] def initialize_image_series(self): pass
[docs] def get_images_in_series(self): '''Should return a single numpy array''' pass
[docs] def close_image_series(self): pass
[docs] def get_image(self): '''Should return a single numpy array''' pass
[docs] def initialize_live_mode(self): pass
[docs] def get_live_image(self): pass
[docs] def close_live_mode(self): pass
[docs] class mesoSPIM_DemoCamera(mesoSPIM_GenericCamera): def __init__(self, parent): super().__init__(parent) self.count = 0 self.line = np.linspace(0,6*np.pi,self.x_pixels) self.line = 400*np.sin(self.line)+1200
[docs] def open_camera(self): logger.info('Initialized Demo Camera')
[docs] def close_camera(self): logger.info('Closed Demo Camera')
[docs] def set_binning(self, binning_string): self.x_binning = int(binning_string[0]) self.y_binning = int(binning_string[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) ''' Changing the number of pixels also affects the random image, so we need to update self.line ''' self.line = np.linspace(0,6*np.pi,self.x_pixels) self.line = 400*np.sin(self.line)+1200 self.state['camera_binning'] = str(self.x_binning)+'x'+str(self.y_binning)
def _create_random_image(self): data = np.array([np.roll(self.line, 4*i + self.count) for i in range(0, self.y_pixels)], dtype='uint16') self.count += 20 return data
[docs] def get_images_in_series(self): return [self._create_random_image()]
[docs] def get_image(self): return self._create_random_image()
[docs] def get_live_image(self): return [self._create_random_image()]
[docs] class mesoSPIM_HamamatsuCamera(mesoSPIM_GenericCamera): def __init__(self, parent): super().__init__(parent)
[docs] def open_camera(self): ''' Hamamatsu-specific code ''' self.camera_id = self.cfg.camera_parameters['camera_id'] from .devices.cameras.hamamatsu import hamamatsu_camera as cam # if self.cfg.camera == 'HamamatsuOrca': self.hcam = cam.HamamatsuCameraMR(camera_id=self.camera_id) ''' Debbuging information ''' logger.info(f'Initialized Hamamatsu camera model: {self.hcam.getModelInfo(self.camera_id)}') ''' Ideally, the Hamamatsu Camera properties should be set in this order ''' ''' mesoSPIM mode parameters ''' self.hcam.setPropertyValue("sensor_mode", self.cfg.camera_parameters['sensor_mode']) self.hcam.setPropertyValue("defect_correct_mode", self.cfg.camera_parameters['defect_correct_mode']) self.hcam.setPropertyValue("binning", self.cfg.camera_parameters['binning']) if 'readout_speed' in self.cfg.camera_parameters.keys(): self.hcam.setPropertyValue("readout_speed", self.cfg.camera_parameters['readout_speed']) else: logger.warning('No readout speed specified in the configuration file. Using default value.') if 'high_dynamic_range_mode' in self.cfg.camera_parameters.keys(): self.hcam.setPropertyValue("high_dynamic_range_mode", self.cfg.camera_parameters['high_dynamic_range_mode']) else: logger.warning('No "high_dynamic_range_mode" specified in the configuration file. Using default value.') self.hcam.setPropertyValue("trigger_active", self.cfg.camera_parameters['trigger_active']) self.hcam.setPropertyValue("trigger_mode", self.cfg.camera_parameters['trigger_mode']) # it is unclear if this is the external lightsheeet mode - how to check this? self.hcam.setPropertyValue("trigger_polarity", self.cfg.camera_parameters['trigger_polarity']) # positive pulse self.hcam.setPropertyValue("trigger_source", self.cfg.camera_parameters['trigger_source']) # external self.hcam.setPropertyValue("internal_line_interval",self.camera_line_interval) self.hcam.setPropertyValue("exposure_time", self.camera_exposure_time) self.print_camera_properties(message='Camera properties after initialization')
[docs] def print_camera_properties(self, message='Camera properties'): ''' Camera properties ''' logger.debug(message) props = self.hcam.getProperties() for i, id_name in enumerate(sorted(props.keys())): [p_value, p_type] = self.hcam.getPropertyValue(id_name) p_rw = self.hcam.getPropertyRW(id_name) read_write = "" if p_rw[0]: read_write += "read" if p_rw[1]: read_write += ", write" logger.debug(f" {i} ) {id_name}, = {p_value} type is: {p_type}, {read_write}") text_values = self.hcam.getPropertyText(id_name) if len(text_values) > 0: logger.debug(" option / value") for key in sorted(text_values, key=text_values.get): logger.debug(f" {key} / {text_values[key]}")
[docs] def close_camera(self): self.hcam.shutdown()
[docs] def set_camera_sensor_mode(self, mode): if mode == 'Area': self.hcam.setPropertyValue("sensor_mode", 1) elif mode == 'ASLM': self.hcam.setPropertyValue("sensor_mode", 12) else: print('Camera mode not supported')
[docs] def set_exposure_time(self, time): self.hcam.setPropertyValue("exposure_time", time)
[docs] def set_line_interval(self, time): self.hcam.setPropertyValue("internal_line_interval",self.camera_line_interval)
[docs] def set_binning(self, binningstring): self.hcam.setPropertyValue("binning", binningstring) self.x_binning = int(binningstring[0]) self.y_binning = int(binningstring[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) self.state['camera_binning'] = str(self.x_binning)+'x'+str(self.y_binning)
[docs] def initialize_image_series(self): self.hcam.startAcquisition()
[docs] def get_images_in_series(self): [frames, _] = self.hcam.getFrames() images = [np.reshape(aframe.getData(), (-1,self.x_pixels)) for aframe in frames] return images
[docs] def close_image_series(self): self.hcam.stopAcquisition()
[docs] def get_image(self): [frames, _] = self.hcam.getFrames() images = [np.reshape(aframe.getData(), (-1,self.x_pixels)) for aframe in frames] return images[0]
[docs] def initialize_live_mode(self): self.hcam.setACQMode(mode = "run_till_abort") self.hcam.startAcquisition()
[docs] def get_live_image(self): [frames, _] = self.hcam.getFrames() images = [np.reshape(aframe.getData(), (-1,self.x_pixels)) for aframe in frames] return images
[docs] def close_live_mode(self): self.hcam.stopAcquisition()
[docs] class mesoSPIM_PhotometricsCamera(mesoSPIM_GenericCamera): def __init__(self, parent): super().__init__(parent)
[docs] def open_camera(self): from pyvcam import pvc from pyvcam import constants as const from pyvcam.camera import Camera self.const = const self.pvc = pvc pvc.init_pvcam() self.pvcam = [cam for cam in Camera.detect_camera()][0] self.pvcam.open() self.pvcam.speed_table_index = self.cfg.camera_parameters['speed_table_index'] self.pvcam.exp_mode = self.cfg.camera_parameters['exp_mode'] self.pvcam.set_param(param_id = self.const.PARAM_READOUT_PORT, value = self.cfg.camera_parameters['readout_port']) self.pvcam.set_param(self.const.PARAM_GAIN_INDEX, self.cfg.camera_parameters['gain_index']) self.pvcam.exp_out_mode = self.cfg.camera_parameters['exp_out_mode'] self.pvcam.exp_res = 0 # 0 for ms logger.info('Camera Vendor Name: '+str(self.pvcam.get_param(param_id = self.const.PARAM_VENDOR_NAME))) logger.info('Camera Product Name: '+str(self.pvcam.get_param(param_id = self.const.PARAM_PRODUCT_NAME))) logger.info('Camera Chip Name: '+str(self.pvcam.get_param(param_id = self.const.PARAM_CHIP_NAME))) logger.info('Camera System Name: '+str(self.pvcam.get_param(param_id = self.const.PARAM_SYSTEM_NAME))) # Exposure mode options: {'Internal Trigger': 1792, 'Edge Trigger': 2304, 'Trigger first': 2048} # self.pvcam.set_param(param_id = self.const.PARAM_EXPOSURE_MODE, value = 2304) # Exposure out mode options: {'First Row': 0, 'All Rows': 1, 'Any Row': 2, 'Rolling Shutter': 3, 'Line Output': 4} # self.pvcam.set_param(param_id = self.const.PARAM_EXPOSE_OUT_MODE, value = 3) ''' Setting ASLM parameters ''' # Scan mode options: {'Auto': 0, 'Line Delay': 1, 'Scan Width': 2} self.pvcam.set_param(param_id = self.const.PARAM_SCAN_MODE, value = self.cfg.camera_parameters['scan_mode']) # Scan direction options: {'Down': 0, 'Up': 1, 'Down/Up Alternate': 2} self.pvcam.set_param(param_id = self.const.PARAM_SCAN_DIRECTION, value = self.cfg.camera_parameters['scan_direction']) # 10.26 us x factor # factor = 6 equals 71.82 us self.pvcam.set_param(param_id = self.const.PARAM_SCAN_LINE_DELAY, value = self.cfg.camera_parameters['scan_line_delay']) ''' Setting Binning parameters: ''' ''' self.binning_string = self.cfg.camera_parameters['binning'] # Should return a string in the form '2x4' self.x_binning = int(self.binning_string[0]) self.y_binning = int(self.binning_string[2]) ''' self.pvcam.binning = (self.x_binning, self.y_binning) #self.pvcam.set_param(param_id = self.const.PARAM_BINNING_PAR, value = self.y_binning) #self.pvcam.set_param(param_id = self.const.PARAM_BINNING_SER, value = self.x_binning) # print('Readout port: ', self.pvcam.readout_port) """ self.report_pvcam_parameter('PMODE',self.const.PARAM_PMODE) self.report_pvcam_parameter('GAIN_INDEX',self.const.PARAM_GAIN_INDEX) self.report_pvcam_parameter('GAIN_NAME',self.const.PARAM_GAIN_NAME) self.report_pvcam_parameter('READOUT PORT',self.const.PARAM_READOUT_PORT) self.report_pvcam_parameter('READOUT TIME',self.const.PARAM_READOUT_TIME) self.report_pvcam_parameter('IMAGE FORMAT', self.const.PARAM_IMAGE_FORMAT) self.report_pvcam_parameter('SPEED TABLE INDEX', self.const.PARAM_SPDTAB_INDEX) self.report_pvcam_parameter('BIT DEPTH', self.const.PARAM_BIT_DEPTH) logger.info('P Mode: '+str(self.pvcam.get_param(param_id = self.const.PARAM_PMODE))) logger.info('P Mode options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_PMODE))) logger.info('Bit depth: '+str(self.pvcam.get_param(param_id = self.const.PARAM_BIT_DEPTH))) logger.info('Exposure time resolution: '+str(self.pvcam.get_param(param_id = self.const.PARAM_EXP_RES))) logger.info('Exposure time resolution options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_EXP_RES))) logger.info('Exposure mode: '+str(self.pvcam.get_param(param_id = self.const.PARAM_EXPOSURE_MODE))) logger.info('Exposure mode options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_EXPOSURE_MODE))) logger.info('Exposure out mode: '+str(self.pvcam.get_param(param_id = self.const.PARAM_EXPOSE_OUT_MODE))) logger.info('Exposure out mode options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_EXPOSE_OUT_MODE))) logger.info('Scan mode: '+str(self.pvcam.get_param(param_id = self.const.PARAM_SCAN_MODE))) logger.info('Scan mode options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_SCAN_MODE))) logger.info('Scan direction: '+str(self.pvcam.get_param(param_id = self.const.PARAM_SCAN_DIRECTION))) logger.info('Scan direction options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_SCAN_DIRECTION))) logger.info('Line delay: '+str(self.pvcam.get_param(param_id = self.const.PARAM_SCAN_LINE_DELAY))) logger.info('Line time: '+str(self.pvcam.get_param(param_id = self.const.PARAM_SCAN_LINE_TIME))) logger.info('Binning SER: '+str(self.pvcam.get_param(param_id = self.const.PARAM_BINNING_SER))) logger.info('Binning SER options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_BINNING_SER))) logger.info('Binning PAR: '+str(self.pvcam.get_param(param_id = self.const.PARAM_BINNING_PAR))) logger.info('Binning PAR options: '+str(self.pvcam.read_enum(param_id = self.const.PARAM_BINNING_PAR))) """
[docs] def report_pvcam_parameter(self, description, parameter): try: logger.info(description+' '+str(self.pvcam.get_param(param_id = parameter))) print(description+' '+str(self.pvcam.get_param(param_id = parameter))) except: pass try: logger.info(description+' '+str(self.pvcam.read_enum(param_id = parameter))) print(description+' '+str(str(self.pvcam.read_enum(param_id = parameter)))) except: pass
[docs] def close_camera(self): self.pvcam.close() self.pvc.uninit_pvcam()
[docs] def set_exposure_time(self, time): print('Exp Time :', time) exp_time_ms = int(self.camera_exposure_time * 1000) self.pvcam.exp_time = exp_time_ms self.camera_exposure_time = time
[docs] def set_line_interval(self, time): print('Setting line interval is not implemented, set the interval in the config file')
[docs] def set_binning(self, binningstring): self.x_binning = int(binningstring[0]) self.y_binning = int(binningstring[2]) self.x_pixels = int(self.x_pixels / self.x_binning) self.y_pixels = int(self.y_pixels / self.y_binning) self.pvcam.binning = (self.x_binning, self.y_binning) self.state['camera_binning'] = str(self.x_binning)+'x'+str(self.y_binning)
[docs] def get_image(self): frame , _ , _ = self.pvcam.poll_frame() return frame['pixel_data']
[docs] def initialize_image_series(self): ''' The Photometrics cameras expect integer exposure times, otherwise they default to the minimum value ''' exp_time_ms = int(self.camera_exposure_time * 1000) self.pvcam.exp_time = exp_time_ms self.pvcam.start_live()
[docs] def get_images_in_series(self): # print('Exp Time in series:', self.pvcam.exp_time) frame , _ , _ = self.pvcam.poll_frame() return [frame['pixel_data']]
[docs] def close_image_series(self): logger.debug("Calling self.pvcam.finish()") self.pvcam.finish()
[docs] def initialize_live_mode(self): ''' The Photometrics cameras expect integer exposure times, otherwise they default to the minimum value ''' exp_time_ms = int(self.camera_exposure_time * 1000) self.pvcam.exp_time = exp_time_ms self.pvcam.start_live() logger.info('Initializing live mode with exp time: '+str(exp_time_ms))
[docs] def get_live_image(self): # print('Exp Time in live:', self.pvcam.exp_time) frame , _ , _ = self.pvcam.poll_frame() return [frame['pixel_data']]
[docs] def close_live_mode(self): # print('Live mode finished') self.pvcam.finish()
[docs] class mesoSPIM_PCOCamera(mesoSPIM_GenericCamera): def __init__(self, parent): super().__init__(parent) logger.info('PCO Cam initialized')
[docs] def open_camera(self): import pco self.cam = pco.Camera() # no logging # self.cam = pco.Camera(debuglevel='verbose', timestamp='on') self.cam.sdk.set_cmos_line_timing('on', self.cfg.camera_parameters['line_interval']) # 75 us delay self.cam.set_exposure_time(self.cfg.camera_parameters['exp_time']) # self.cam.sdk.set_cmos_line_exposure_delay(80, 0) # 266 lines = 20 ms / 75 us self.cam.configuration = {'trigger' : self.cfg.camera_parameters['trigger']} line_time = self.cam.sdk.get_cmos_line_timing()['line time'] lines_exposure = self.cam.sdk.get_cmos_line_exposure_delay()['lines exposure'] t = self.cam.get_exposure_time() #print('Exposure Time: {:9.6f} s'.format(t)) #print('Line Time: {:9.6f} s'.format(line_time)) #print('Number of Lines: {:d}'.format(lines_exposure)) self.cam.record(number_of_images=4, mode='fifo')
[docs] def close_camera(self): self.cam.stop() self.cam.close()
[docs] def set_exposure_time(self, time): self.cam.set_exposure_time(time) self.camera_exposure_time = time
[docs] def set_line_interval(self, time): print('Setting line interval is not implemented, set the interval in the config file')
[docs] def set_binning(self, binningstring): pass
[docs] def get_image(self): image, meta = self.cam.image(image_number=-1) return image
[docs] def initialize_image_series(self): pass
[docs] def get_images_in_series(self): image, meta = self.cam.image(image_number=-1) return [image]
[docs] def close_image_series(self): pass
[docs] def initialize_live_mode(self): pass
[docs] def get_live_image(self): image, meta = self.cam.image(image_number=-1) return [image]
[docs] def close_live_mode(self): pass