Skip to content

Commit fb701eb

Browse files
Ian Dobbiemickp
authored andcommitted
Added ximea.py camera driver based on testcamera
1 parent faf44a9 commit fb701eb

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

microscope/cameras/ximea.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
## Copyright (C) 2016-2017 Mick Phillips <mick.phillips@gmail.com>
5+
## Copyright (C) 2017 Ian Dobbie <ian.dobbie@bioch.ox.ac.uk>
6+
##
7+
## This file is part of Microscope.
8+
##
9+
## Microscope is free software: you can redistribute it and/or modify
10+
## it under the terms of the GNU General Public License as published by
11+
## the Free Software Foundation, either version 3 of the License, or
12+
## (at your option) any later version.
13+
##
14+
## Microscope is distributed in the hope that it will be useful,
15+
## but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
## GNU General Public License for more details.
18+
##
19+
## You should have received a copy of the GNU General Public License
20+
## along with Microscope. If not, see <http://www.gnu.org/licenses/>.
21+
22+
import time
23+
24+
import Pyro4
25+
import numpy as np
26+
27+
from microscope import devices
28+
from microscope.devices import keep_acquiring
29+
from microscope.filterwheel import FilterWheelBase
30+
31+
#import ximea python module.
32+
from ximea import xiapi
33+
34+
35+
@Pyro4.expose
36+
@Pyro4.behavior('single')
37+
class XimaeCamera(devices.CameraDevice):
38+
def __init__(self, *args, **kwargs):
39+
super(XimaeCamera, self).__init__(**kwargs)
40+
#example parameter to allow setting.
41+
# self.add_setting('_error_percent', 'int',
42+
# lambda: self._error_percent,
43+
# self._set_error_percent,
44+
# lambda: (0, 100))
45+
self._acquiring = False
46+
self._exposure_time = 0.1
47+
self._triggered = False
48+
49+
def _purge_buffers(self):
50+
"""Purge buffers on both camera and PC."""
51+
self._logger.info("Purging buffers.")
52+
53+
def _create_buffers(self):
54+
"""Create buffers and store values needed to remove padding later."""
55+
self._purge_buffers()
56+
self._logger.info("Creating buffers.")
57+
#time.sleep(0.5)
58+
59+
def _fetch_data(self):
60+
if self._acquiring and self._triggered:
61+
self.handle.get_image(self.img)
62+
self._logger.info('Sending image')
63+
self._triggered = False
64+
return self.img.get_image_data_raw()
65+
66+
def abort(self):
67+
self._logger.info('Disabling acquisition.')
68+
if self._acquiring:
69+
self._acquiring = False
70+
self.handle.stop_acquisition()
71+
72+
def initialize(self):
73+
"""Initialise the camera.
74+
75+
Open the connection, connect properties and populate settings dict.
76+
"""
77+
78+
try:
79+
self.handle = xiapi.Camera()
80+
self.handle.open_device()
81+
except:
82+
raise Exception("Problem opening camera.")
83+
if self.handle == None:
84+
raise Exception("No camera opened.")
85+
86+
# for name, var in sorted(self.__dict__.items()):
87+
self._logger.info('Initializing.')
88+
#create img buffer to hold images.
89+
self.img=xiapi.Image()
90+
91+
def make_safe(self):
92+
if self._acquiring:
93+
self.abort()
94+
95+
def _on_disable(self):
96+
self.abort()
97+
98+
def _on_enable(self):
99+
self._logger.info("Preparing for acquisition.")
100+
if self._acquiring:
101+
self.abort()
102+
self._create_buffers()
103+
self._acquiring = True
104+
#actually start camera
105+
self.handle.start_acquisition()
106+
self._logger.info("Acquisition enabled.")
107+
return True
108+
109+
def set_exposure_time(self, value):
110+
#exposure times are set in us.
111+
self.handle.set_exposure(value*1.0E6)
112+
113+
def get_exposure_time(self):
114+
#exposure times are in us, so multiple by 1E-6 to get seconds.
115+
return (self.handle.get_exposure()*1.0E-6)
116+
117+
def get_cycle_time(self):
118+
return (self.handle.get_exposure()*1.0E-6)
119+
120+
def _get_sensor_shape(self):
121+
return (self.img.width,self.image.height)
122+
123+
def get_trigger_type(self):
124+
return devices.TRIGGER_SOFT
125+
126+
def soft_trigger(self):
127+
self._logger.info('Trigger received; self._acquiring is %s.'
128+
% self._acquiring)
129+
if self._acquiring:
130+
self._triggered = True
131+
132+
def _get_binning(self):
133+
return (1,1)
134+
135+
@keep_acquiring
136+
def _set_binning(self, h, v):
137+
return False
138+
139+
def _get_roi(self):
140+
return (0, 0, 512, 512)
141+
142+
@keep_acquiring
143+
def _set_roi(self, x, y, width, height):
144+
return False
145+
146+
def _on_shutdown(self):
147+
if self_.acquiring:
148+
self.handle.stop_acquisition()
149+
self.handle.close_device()
150+

0 commit comments

Comments
 (0)