def _get_roi(self) -> devices.ROI: assert self._roi == devices.ROI(self._handle.get_offsetX(), self._handle.get_offsetY(), self._handle.get_width(), self._handle.get_height()), \ "ROI attribute is out of sync with internal camera setting" return self._roi
def __init__(self, serial_number: typing.Optional[str] = None, **kwargs) -> None: super().__init__(**kwargs) self._acquiring = False self._handle = xiapi.Camera() self._img = xiapi.Image() self._serial_number = serial_number self._sensor_shape = (0, 0) self._roi = devices.ROI(None, None, None, None) self._binning = devices.Binning(1, 1) # When using the Settings system, enums are not really enums # and even when using lists we get indices sent back and forth # (works fine only when using EnumInt. The gymnastic here # makes it work with the rest of enums which are there to make # it work with TriggerTypeMixIn. trg_source_names = [x.name for x in TrgSourceMap] def _trigger_source_setter(index: int) -> None: trigger_mode = TrgSourceMap[trg_source_names[index]].value self.set_trigger(trigger_mode, self.trigger_mode) self.add_setting('trigger source', 'enum', lambda: TrgSourceMap(self.trigger_type).name, _trigger_source_setter, trg_source_names)
def initialize(self) -> None: """Initialise the camera. Open the connection, connect properties and populate settings dict. """ n_cameras = self._handle.get_number_devices() if self._serial_number is None: if n_cameras > 1: raise Exception('more than one Ximea camera found but the' ' serial_number argument was not specified') _logger.info('serial_number is not specified but there is only one' ' camera on the system') self._handle.open_device() else: _logger.info('opening camera with serial number \'%s\'', self._serial_number) self._handle.open_device_by_SN(self._serial_number) # Camera.dev_id defaults to zero. However, after opening # the device by serial number is is not updated (see # https://github.com/python-microscope/vendor-issues/issues/1). # So we manually iterate over each possible device ID and # modify dev_id until it behaves as it should. If we # don't fix this and there are multiple cameras connected, # some of the handle methods will return info from another # camera. for dev_id in range(n_cameras): self._handle.dev_id = dev_id if (self._serial_number.encode() == self._handle.get_device_info_string('device_sn')): break else: raise Exception('failed to get DevId for device with SN %s' % self._serial_number) self._sensor_shape = (self._handle.get_width_maximum() + self._handle.get_offsetX_maximum(), self._handle.get_height_maximum() + self._handle.get_offsetY_maximum()) self._roi = devices.ROI(left=0, top=0, width=self._sensor_shape[0], height=self._sensor_shape[1]) self.set_roi(self._roi) self.set_trigger(devices.TriggerType.SOFTWARE, devices.TriggerMode.ONCE) # When we return the sensor temperature we want to return the # temperature that's closest to the chip since that's the one # that has the biggest impact on image noise. We don't know # what temperature sensors each camera has so we try one at a # time, by order of preference, until it works. for temperature_selector in ('XI_TEMP_IMAGE_SENSOR_DIE', 'XI_TEMP_IMAGE_SENSOR_DIE_RAW', 'XI_TEMP_SENSOR_BOARD', 'XI_TEMP_INTERFACE_BOARD', 'XI_TEMP_FRONT_HOUSING', 'XI_TEMP_REAR_HOUSING', 'XI_TEMP_TEC1_COLD', 'XI_TEMP_TEC1_HOT'): try: self._handle.set_temp_selector(temperature_selector) except xiapi.Xi_error as err: if getattr(err, 'status', None) == 12: # Not supported _logger.info('no hardware support for %s temperature' ' readings', temperature_selector) if getattr(err, 'status', None) == 26: # Not implemented _logger.info('%s temperature readings are not' ' implemented on this hardware', temperature_selector) else: raise else: _logger.info('temperature reading set to %s', temperature_selector) break