BioImager  4.9.0
A .NET microscopy imaging application based on Bio library. Supports various microscopes by using imported libraries & GUI automation. Supports XInput game controllers to move stage, take images, run ImageJ macros on images or Bio C# scripts.
Loading...
Searching...
No Matches
microscope.cameras.ximea.XimeaCamera Class Reference
Inheritance diagram for microscope.cameras.ximea.XimeaCamera:
microscope.abc.Camera microscope.abc.TriggerTargetMixin microscope.abc.DataDevice microscope.abc.Device

Public Member Functions

None __init__ (self, typing.Optional[str] serial_number=None, **kwargs)
 
 abort (self)
 
None initialize (self)
 
None set_exposure_time (self, float value)
 
float get_exposure_time (self)
 
 get_cycle_time (self)
 
None soft_trigger (self)
 
microscope.TriggerMode trigger_mode (self)
 
microscope.TriggerType trigger_type (self)
 
None set_trigger (self, microscope.TriggerType ttype, microscope.TriggerMode tmode)
 
- Public Member Functions inherited from microscope.abc.Camera
 set_readout_mode (self, description)
 
 get_transform (self)
 
 set_transform (self, transform)
 
typing.Tuple[int, int] get_sensor_shape (self)
 
microscope.Binning get_binning (self)
 
None set_binning (self, microscope.Binning binning)
 
microscope.ROI get_roi (self)
 
None set_roi (self, microscope.ROI roi)
 
- Public Member Functions inherited from microscope.abc.TriggerTargetMixin
None trigger (self)
 
- Public Member Functions inherited from microscope.abc.DataDevice
 __del__ (self)
 
None enable (self)
 
None disable (self)
 
None set_client (self, new_client)
 
None update_settings (self, settings, bool init=False)
 
None receiveClient (self, str client_uri)
 
 grab_next_data (self, bool soft_trigger=True)
 
None receiveData (self, data, timestamp)
 
- Public Member Functions inherited from microscope.abc.Device
bool get_is_enabled (self)
 
None shutdown (self)
 
None add_setting (self, name, dtype, get_func, set_func, values, typing.Optional[typing.Callable[[], bool]] readonly=None)
 
 get_setting (self, str name)
 
 get_all_settings (self)
 
None set_setting (self, str name, value)
 
 describe_setting (self, str name)
 
 describe_settings (self)
 

Public Attributes

 trigger_mode
 
 trigger_type
 
- Public Attributes inherited from microscope.abc.Camera
 set_readout_mode
 
 get_roi
 
 set_roi
 
- Public Attributes inherited from microscope.abc.DataDevice
bool enabled = False
 
bool _fetch_thread = True
 
bool _dispatch_thread = True
 
None _fetch_thread_run = self._fetch_data()
 
- Public Attributes inherited from microscope.abc.Device
bool enabled = False
 

Protected Member Functions

typing.Optional[np.ndarray] _fetch_data (self)
 
 _do_disable (self)
 
 _do_enable (self)
 
typing.Tuple[int, int] _get_sensor_shape (self)
 
None _do_trigger (self)
 
microscope.Binning _get_binning (self)
 
bool _set_binning (self, microscope.Binning binning)
 
microscope.ROI _get_roi (self)
 
bool _set_roi (self, microscope.ROI roi)
 
None _do_shutdown (self)
 
- Protected Member Functions inherited from microscope.abc.Camera
 _process_data (self, data)
 
 _set_readout_transform (self, new_transform)
 
- Protected Member Functions inherited from microscope.abc.TriggerTargetMixin
- Protected Member Functions inherited from microscope.abc.DataDevice
 _send_data (self, client, data, timestamp)
 
None _dispatch_loop (self)
 
None _fetch_loop (self)
 
 _client (self)
 
 _client (self, val)
 
None _put (self, data, timestamp)
 
- Protected Member Functions inherited from microscope.abc.Device

Protected Attributes

bool _acquiring = False
 
 _handle = xiapi.Camera()
 
 _img = xiapi.Image()
 
 _serial_number = serial_number
 
tuple _sensor_shape = (0, 0)
 
str _roi = microscope.ROI(None, None, None, None)
 
 _binning = microscope.Binning(1, 1)
 
- Protected Attributes inherited from microscope.abc.Camera
list _readout_modes = ["default"]
 
int _readout_mode = 0
 
tuple _readout_transform = (False, False, False)
 
tuple _client_transform = (False, False, False)
 
tuple _transform = (False, False, False)
 
- Protected Attributes inherited from microscope.abc.DataDevice
 _fetch_thread = None
 
bool _fetch_thread_run = False
 
bool _using_callback = False
 
list _clientStack = []
 
 _liveClients = set()
 
 _dispatch_thread = None
 
 _dispatch_buffer = queue.Queue(maxsize=buffer_length)
 
bool _acquiring = False
 
 _new_data_condition = threading.Condition()
 
 _client = None
 
tuple _new_data = (data, timestamp)
 
- Protected Attributes inherited from microscope.abc.Device
dict _settings = {}
 

Additional Inherited Members

- Static Public Attributes inherited from microscope.abc.Camera
list ALLOWED_TRANSFORMS = [p for p in itertools.product(*3 * [[False, True]])]
 
- Static Public Attributes inherited from microscope.abc.DataDevice
 set_setting = keep_acquiring(Device.set_setting)
 

Detailed Description

Ximea cameras

Args:
    serial_number: the serial number of the camera to connect to.
        It can be set to `None` if there is only camera on the
        system.

Definition at line 176 of file ximea.py.

Constructor & Destructor Documentation

◆ __init__()

None microscope.cameras.ximea.XimeaCamera.__init__ ( self,
typing.Optional[str] buffer_length = None,
** kwargs )
Derived.__init__ must call this at some point.

Reimplemented from microscope.abc.Camera.

Definition at line 186 of file ximea.py.

188 ) -> None:
189 super().__init__(**kwargs)
190 self._acquiring = False
191 self._handle = xiapi.Camera()
192 self._img = xiapi.Image()
193 self._serial_number = serial_number
194 self._sensor_shape = (0, 0)
195 self._roi = microscope.ROI(None, None, None, None)
196 self._binning = microscope.Binning(1, 1)
197
198 # When using the Settings system, enums are not really enums
199 # and even when using lists we get indices sent back and forth
200 # (works fine only when using EnumInt. The gymnastic here
201 # makes it work with the rest of enums which are there to make
202 # it work with TriggerTargetMixin.
203 trg_source_names = [x.name for x in TrgSourceMap]
204
205 def _trigger_source_setter(index: int) -> None:
206 trigger_mode = TrgSourceMap[trg_source_names[index]].value
207 self.set_trigger(trigger_mode, self.trigger_mode)
208
209 self.add_setting(
210 "trigger source",
211 "enum",
212 lambda: TrgSourceMap(self.trigger_type).name,
213 _trigger_source_setter,
214 trg_source_names,
215 )
216
217 self.initialize()
218

Member Function Documentation

◆ _do_disable()

microscope.cameras.ximea.XimeaCamera._do_disable ( self)
protected
Do any device-specific work on disable.

Subclasses should override this method rather than modify
`disable`.

Reimplemented from microscope.abc.Device.

Definition at line 335 of file ximea.py.

335 def _do_disable(self):
336 self.abort()
337

◆ _do_enable()

microscope.cameras.ximea.XimeaCamera._do_enable ( self)
protected
Do any device specific work on enable.

Subclasses should override this method, rather than modify
`enable`.

Reimplemented from microscope.abc.Device.

Definition at line 338 of file ximea.py.

338 def _do_enable(self):
339 _logger.info("Preparing for acquisition.")
340 if self._acquiring:
341 self.abort()
342 # actually start camera
343 self._handle.start_acquisition()
344 self._acquiring = True
345 _logger.info("Acquisition enabled.")
346 return True
347

◆ _do_shutdown()

None microscope.cameras.ximea.XimeaCamera._do_shutdown ( self)
protected
Private method - actual shutdown of the device.

Users should be calling :meth:`shutdown` and not this method.
Concrete implementations should implement this method instead
of `shutdown`.

Reimplemented from microscope.abc.Device.

Definition at line 423 of file ximea.py.

423 def _do_shutdown(self) -> None:
424 if self._acquiring:
425 self._handle.stop_acquisition()
426 if self._handle.CAM_OPEN:
427 # We check CAM_OPEN instead of try/catch an exception
428 # because if the camera failed initialisation, XiApi fails
429 # hard with error code -1009 (unknown) since the internal
430 # device handler is NULL.
431 self._handle.close_device()
432

◆ _do_trigger()

None microscope.cameras.ximea.XimeaCamera._do_trigger ( self)
protected
Actual trigger of the device.

Classes implementing this interface should implement this
method instead of `trigger`.

Reimplemented from microscope.abc.TriggerTargetMixin.

Definition at line 368 of file ximea.py.

368 def _do_trigger(self) -> None:
369 # Value for set_trigger_software() has no meaning. See
370 # https://github.com/python-microscope/vendor-issues/issues/3
371 self._handle.set_trigger_software(1)
372

◆ _fetch_data()

typing.Optional[np.ndarray] microscope.cameras.ximea.XimeaCamera._fetch_data ( self)
protected
Poll for data and return it, with minimal processing.

If the device uses buffering in software, this function should
copy the data from the buffer, release or recycle the buffer,
then return a reference to the copy.  Otherwise, if the SDK
returns a data object that will not be written to again, this
function can just return a reference to the object.  If no
data is available, return `None`.

Reimplemented from microscope.abc.DataDevice.

Definition at line 219 of file ximea.py.

219 def _fetch_data(self) -> typing.Optional[np.ndarray]:
220 if not self._acquiring:
221 return None
222
223 try:
224 self._handle.get_image(self._img, timeout=1)
225 except xiapi.Xi_error as err:
226 # err.status may not exist so use getattr (see
227 # https://github.com/python-microscope/vendor-issues/issues/2)
228 if getattr(err, "status", None) == _XI_TIMEOUT:
229 return None
230 elif (
231 getattr(err, "status", None) == _XI_ACQUISITION_STOPED
232 and not self._acquiring
233 ):
234 # We can end up here during disable if self._acquiring
235 # was True but is now False.
236 return None
237 else:
238 raise
239
240 data: np.ndarray = self._img.get_image_data_numpy()
241 _logger.info(
242 "Fetched imaged with dims %s and size %s.", data.shape, data.size
243 )
244 return data
245

◆ _get_binning()

microscope.Binning microscope.cameras.ximea.XimeaCamera._get_binning ( self)
protected
Return the current binning.

Reimplemented from microscope.abc.Camera.

Definition at line 373 of file ximea.py.

373 def _get_binning(self) -> microscope.Binning:
374 return self._binning
375

◆ _get_roi()

microscope.ROI microscope.cameras.ximea.XimeaCamera._get_roi ( self)
protected
Return the ROI as it is on hardware.

Reimplemented from microscope.abc.Camera.

Definition at line 385 of file ximea.py.

385 def _get_roi(self) -> microscope.ROI:
386 assert self._roi == microscope.ROI(
387 self._handle.get_offsetX(),
388 self._handle.get_offsetY(),
389 self._handle.get_width(),
390 self._handle.get_height(),
391 ), "ROI attribute is out of sync with internal camera setting"
392 return self._roi
393

◆ _get_sensor_shape()

typing.Tuple[int, int] microscope.cameras.ximea.XimeaCamera._get_sensor_shape ( self)
protected
Return a tuple of `(width, height)` indicating shape in pixels.

Reimplemented from microscope.abc.Camera.

Definition at line 362 of file ximea.py.

362 def _get_sensor_shape(self) -> typing.Tuple[int, int]:
363 return self._sensor_shape
364

◆ _set_binning()

bool microscope.cameras.ximea.XimeaCamera._set_binning ( self,
microscope.Binning binning )
protected
Set binning along both axes.  Return `True` if successful.

Reimplemented from microscope.abc.Camera.

Definition at line 376 of file ximea.py.

376 def _set_binning(self, binning: microscope.Binning) -> bool:
377 if binning == self._binning:
378 return True
379 # We don't have a ximea camera that supports binning so we
380 # can't write support for this (a camera without this feature
381 # will raise error 100). When writing this, careful and check
382 # what XiAPI does when mixing ROI and binning.
383 raise NotImplementedError()
384

◆ _set_roi()

bool microscope.cameras.ximea.XimeaCamera._set_roi ( self,
microscope.ROI roi )
protected
Set the ROI on the hardware.  Return `True` if successful.

Reimplemented from microscope.abc.Camera.

Definition at line 394 of file ximea.py.

394 def _set_roi(self, roi: microscope.ROI) -> bool:
395 if (
396 roi.width + roi.left > self._sensor_shape[0]
397 or roi.height + roi.top > self._sensor_shape[1]
398 ):
399 raise ValueError(
400 "ROI %s does not fit in sensor shape %s"
401 % (roi, self._sensor_shape)
402 )
403 try:
404 # These methods will fail if the width/height plus their
405 # corresponding offsets are higher than the sensor size.
406 # So we start by setting the offset to zero. Cases to
407 # think off: 1) shrinking ROI size, 2) increasing ROI
408 # size, 3) resetting ROI and so can't trust self._roi as
409 # the current state (see this exception handling).
410 with _disabled_camera(self):
411 self._handle.set_offsetX(0)
412 self._handle.set_offsetY(0)
413 self._handle.set_width(roi.width)
414 self._handle.set_height(roi.height)
415 self._handle.set_offsetX(roi.left)
416 self._handle.set_offsetY(roi.top)
417 except Exception:
418 self._set_roi(self._roi) # set it back to whatever was before
419 raise
420 self._roi = roi
421 return True
422

◆ abort()

microscope.cameras.ximea.XimeaCamera.abort ( self)
Stop acquisition as soon as possible.

Reimplemented from microscope.abc.DataDevice.

Definition at line 246 of file ximea.py.

246 def abort(self):
247 _logger.info("Disabling acquisition.")
248 if self._acquiring:
249 # We set acquiring before calling stop_acquisition because
250 # the fetch loop is still running and will raise errors 45
251 # otherwise.
252 self._acquiring = False
253 try:
254 self._handle.stop_acquisition()
255 except Exception:
256 self._acquiring = True
257 raise
258

◆ get_cycle_time()

microscope.cameras.ximea.XimeaCamera.get_cycle_time ( self)
Return the cycle time in seconds.

Reimplemented from microscope.abc.Camera.

Definition at line 359 of file ximea.py.

359 def get_cycle_time(self):
360 return 1.0 / self._handle.get_framerate()
361

◆ get_exposure_time()

float microscope.cameras.ximea.XimeaCamera.get_exposure_time ( self)
Return the current exposure time in seconds.

Reimplemented from microscope.abc.Camera.

Definition at line 355 of file ximea.py.

355 def get_exposure_time(self) -> float:
356 # exposure times are in us, so multiple by 1E-6 to get seconds.
357 return self._handle.get_exposure() * 1.0e-6
358

◆ initialize()

None microscope.cameras.ximea.XimeaCamera.initialize ( self)
Initialise the camera.

Open the connection, connect properties and populate settings dict.

Reimplemented from microscope.abc.Device.

Definition at line 259 of file ximea.py.

259 def initialize(self) -> None:
260 """Initialise the camera.
261
262 Open the connection, connect properties and populate settings dict.
263 """
264 n_cameras = self._handle.get_number_devices()
265
266 if self._serial_number is None:
267 if n_cameras > 1:
268 raise TypeError(
269 "more than one Ximea camera found but the"
270 " serial_number argument was not specified"
271 )
272 _logger.info(
273 "serial_number is not specified but there is only one"
274 " camera on the system"
275 )
276 self._handle.open_device()
277 else:
278 _logger.info(
279 "opening camera with serial number '%s'", self._serial_number
280 )
281 self._handle.open_device_by_SN(self._serial_number)
282
283 self._sensor_shape = (
284 self._handle.get_width_maximum()
285 + self._handle.get_offsetX_maximum(),
286 self._handle.get_height_maximum()
287 + self._handle.get_offsetY_maximum(),
288 )
289 self._roi = microscope.ROI(
290 left=0,
291 top=0,
292 width=self._sensor_shape[0],
293 height=self._sensor_shape[1],
294 )
295 self.set_roi(self._roi)
296
297 self.set_trigger(
298 microscope.TriggerType.SOFTWARE, microscope.TriggerMode.ONCE
299 )
300
301 # Add settings for the different temperature sensors.
302 for temp_param_name in [
303 "chip_temp",
304 "hous_temp",
305 "hous_back_side_temp",
306 "sensor_board_temp",
307 ]:
308 get_temp_method = getattr(self._handle, "get_" + temp_param_name)
309 # Not all cameras have temperature sensors in all
310 # locations. We can't query if the sensor is there, we
311 # can only try to read the temperature and skip that
312 # temperature sensor if we get an exception.
313 try:
314 get_temp_method()
315 except xiapi.Xi_error as err:
316 # Depending on XiAPI version, camera model, and
317 # selected sensor, we might get any of these errors as
318 # meaning that it's not available. See
319 # https://github.com/python-microscope/vendor-issues/issues/6
320 if err.status not in [
321 _XI_NOT_SUPPORTED,
322 _XI_NOT_IMPLEMENTED,
323 _XI_UNKNOWN_PARAM,
324 ]:
325 raise
326 else:
327 self.add_setting(
328 temp_param_name,
329 "float",
330 get_temp_method,
331 None,
332 values=tuple(),
333 )
334

◆ set_exposure_time()

None microscope.cameras.ximea.XimeaCamera.set_exposure_time ( self,
float value )
Set the exposure time on the device in seconds.

Reimplemented from microscope.abc.Camera.

Definition at line 348 of file ximea.py.

348 def set_exposure_time(self, value: float) -> None:
349 # exposure times are set in us.
350 try:
351 self._handle.set_exposure_direct(int(value * 1000000))
352 except Exception as err:
353 _logger.debug("set_exposure_time exception: %s", err)
354

◆ set_trigger()

None microscope.cameras.ximea.XimeaCamera.set_trigger ( self,
microscope.TriggerType ttype,
microscope.TriggerMode tmode )
Set device for a specific trigger.

Reimplemented from microscope.abc.TriggerTargetMixin.

Definition at line 455 of file ximea.py.

457 ) -> None:
458 if tmode is not microscope.TriggerMode.ONCE:
460 "%s not supported (only TriggerMode.ONCE)" % tmode
461 )
462
463 try:
464 trg_source = TrgSourceMap(ttype)
465 except ValueError:
467 "no support for trigger type %s" % ttype
468 )
469
470 if trg_source.name != self._handle.get_trigger_source():
471 # Changing trigger source requires stopping acquisition.
472 with _disabled_camera(self):
473 self._handle.set_trigger_source(trg_source.name)

◆ soft_trigger()

None microscope.cameras.ximea.XimeaCamera.soft_trigger ( self)

Definition at line 365 of file ximea.py.

365 def soft_trigger(self) -> None:
366 self.trigger()
367

◆ trigger_mode()

microscope.TriggerMode microscope.cameras.ximea.XimeaCamera.trigger_mode ( self)

Reimplemented from microscope.abc.TriggerTargetMixin.

Definition at line 434 of file ximea.py.

434 def trigger_mode(self) -> microscope.TriggerMode:
435 trg_selector = self._handle.get_trigger_selector()
436 try:
437 tmode = TrgSelectorMap[trg_selector]
438 except KeyError:
439 raise Exception(
440 "somehow set to unsupported trigger mode %s" % trg_selector
441 )
442 return tmode.value
443

◆ trigger_type()

microscope.TriggerType microscope.cameras.ximea.XimeaCamera.trigger_type ( self)

Reimplemented from microscope.abc.TriggerTargetMixin.

Definition at line 445 of file ximea.py.

445 def trigger_type(self) -> microscope.TriggerType:
446 trg_source = self._handle.get_trigger_source()
447 try:
448 ttype = TrgSourceMap[trg_source]
449 except KeyError:
450 raise Exception(
451 "somehow set to unsupported trigger type %s" % trg_source
452 )
453 return ttype.value
454

Member Data Documentation

◆ _acquiring

bool microscope.cameras.ximea.XimeaCamera._acquiring = False
protected

Definition at line 190 of file ximea.py.

◆ _binning

microscope.cameras.ximea.XimeaCamera._binning = microscope.Binning(1, 1)
protected

Definition at line 196 of file ximea.py.

◆ _handle

microscope.cameras.ximea.XimeaCamera._handle = xiapi.Camera()
protected

Definition at line 191 of file ximea.py.

◆ _img

microscope.cameras.ximea.XimeaCamera._img = xiapi.Image()
protected

Definition at line 192 of file ximea.py.

◆ _roi

str microscope.cameras.ximea.XimeaCamera._roi = microscope.ROI(None, None, None, None)
protected

Definition at line 195 of file ximea.py.

◆ _sensor_shape

microscope.cameras.ximea.XimeaCamera._sensor_shape = (0, 0)
protected

Definition at line 194 of file ximea.py.

◆ _serial_number

microscope.cameras.ximea.XimeaCamera._serial_number = serial_number
protected

Definition at line 193 of file ximea.py.

◆ trigger_mode

microscope.cameras.ximea.XimeaCamera.trigger_mode

Definition at line 207 of file ximea.py.

◆ trigger_type

microscope.cameras.ximea.XimeaCamera.trigger_type

Definition at line 212 of file ximea.py.


The documentation for this class was generated from the following file: