2929import Pyro4
3030
3131import microscope
32- #import raspberry pi specific modules
32+
33+ # import raspberry pi specific modules
3334import picamera
3435import picamera .array
35- #to allow hardware trigger.
36+
37+ # to allow hardware trigger.
3638import RPi .GPIO as GPIO
3739from microscope import devices
3840from microscope .devices import ROI , Binning , keep_acquiring
3941
4042
41- GPIO_Trigger = 21
42- GPIO_CAMLED = 5
43+ GPIO_Trigger = 21
44+ GPIO_CAMLED = 5
4345
4446_logger = logging .getLogger (__name__ )
4547
@@ -49,39 +51,41 @@ class TrgSourceMap(enum.Enum):
4951 SOFTWARE = microscope .TriggerType .SOFTWARE
5052 EDGE_RISING = microscope .TriggerType .RISING_EDGE
5153
54+
5255@Pyro4 .expose
53- @Pyro4 .behavior (' single' )
56+ @Pyro4 .behavior (" single" )
5457class PiCamera (microscope .abc .Camera ):
5558 def __init__ (self , * args , ** kwargs ):
5659 super (PiCamera , self ).__init__ (** kwargs )
57- # example parameter to allow setting.
58- # self.add_setting('_error_percent', 'int',
59- # lambda: self._error_percent,
60- # self._set_error_percent,
61- # lambda: (0, 100))
60+ # example parameter to allow setting.
61+ # self.add_setting('_error_percent', 'int',
62+ # lambda: self._error_percent,
63+ # self._set_error_percent,
64+ # lambda: (0, 100))
6265 self ._acquiring = False
6366 self ._exposure_time = 0.1
6467 self ._triggered = False
6568 self .camera = None
6669 # Region of interest.
6770 self .roi = ROI (None , None , None , None )
6871 # Cycle time
69- self .exposure_time = 0.001 # in seconds
72+ self .exposure_time = 0.001 # in seconds
7073 self .cycle_time = self .exposure_time
71- #initialise in soft trigger mode
72- self ._trigger_type = microscope .TriggerType .SOFTWARE
73- #setup hardware triggerline
74+ # initialise in soft trigger mode
75+ self ._trigger_type = microscope .TriggerType .SOFTWARE
76+ # setup hardware triggerline
7477 GPIO .setmode (GPIO .BCM )
75- #GPIO trigger line is an input
76- GPIO .setup (GPIO_Trigger ,GPIO .IN )
77- #GPIO control over camera LED is an output
78- GPIO .setup (GPIO_CAMLED ,GPIO .OUT )
79- #add trigger to settings
78+ # GPIO trigger line is an input
79+ GPIO .setup (GPIO_Trigger , GPIO .IN )
80+ # GPIO control over camera LED is an output
81+ GPIO .setup (GPIO_CAMLED , GPIO .OUT )
82+ # add trigger to settings
8083 trg_source_names = [x .name for x in TrgSourceMap ]
81- #set up queue to store images as they are acquired
84+ # set up queue to store images as they are acquired
8285 self ._queue = queue .Queue ()
83- self ._awb_modes = picamera .PiCamera .AWB_MODES
84- self ._iso_modes = [0 , 100 , 200 , 320 , 400 , 500 , 640 , 800 ]
86+ self ._awb_modes = picamera .PiCamera .AWB_MODES
87+ self ._iso_modes = [0 , 100 , 200 , 320 , 400 , 500 , 640 , 800 ]
88+
8589 def _trigger_source_setter (index : int ) -> None :
8690 trigger_type = TrgSourceMap [trg_source_names [index ]].value
8791 self .set_trigger (trigger_type , self .trigger_mode )
@@ -109,7 +113,6 @@ def _trigger_source_setter(index: int) -> None:
109113 values = (self ._iso_modes ),
110114 )
111115
112-
113116 # self.add_setting(
114117 # "pixel size",
115118 # "float",
@@ -121,28 +124,26 @@ def _trigger_source_setter(index: int) -> None:
121124 self .initialize ()
122125
123126 def get_awb_mode (self ):
124- return ( self .camera .awb_mode )
125-
126- def set_awb_mode (self ,val ):
127- for key , value in self ._awb_modes .items ():
127+ return self .camera .awb_mode
128+
129+ def set_awb_mode (self , val ):
130+ for key , value in self ._awb_modes .items ():
128131 if value == val :
129- self .camera .awb_mode = key
132+ self .camera .awb_mode = key
130133
131- def set_iso_mode (self ,val ):
132- self .camera .iso = self ._iso_modes [val ]
134+ def set_iso_mode (self , val ):
135+ self .camera .iso = self ._iso_modes [val ]
133136
134-
135-
136- def HW_trigger (self ,channel ):
137- '''Function called by GPIO interupt, needs to trigger image capture'''
137+ def HW_trigger (self , channel ):
138+ """Function called by GPIO interupt, needs to trigger image capture"""
138139 with picamera .array .PiYUVArray (self .camera ) as output :
139- self .camera .capture (output , format = ' yuv' , use_video_port = False )
140- self ._queue .put (output .array [:,:, 0 ])
140+ self .camera .capture (output , format = " yuv" , use_video_port = False )
141+ self ._queue .put (output .array [:, :, 0 ])
141142
142143 def _fetch_data (self ):
143144 if self ._queue .qsize () is not 0 :
144- data = self ._queue .get ()
145- _logger .info (' Sending image' )
145+ data = self ._queue .get ()
146+ _logger .info (" Sending image" )
146147 return data
147148 else :
148149 return None
@@ -153,69 +154,71 @@ def initialize(self):
153154 """
154155 if not self .camera :
155156 try :
156- #initialise camera in still image mode.
157- self .camera = picamera .PiCamera (sensor_mode = 2 )
157+ # initialise camera in still image mode.
158+ self .camera = picamera .PiCamera (sensor_mode = 2 )
158159 except :
159160 raise Exception ("Problem opening camera." )
160- _logger .info (' Initializing camera.' )
161- self .camversion = self .camera .revision
162- _logger .info (' cam version ' + self .camversion )
161+ _logger .info (" Initializing camera." )
162+ self .camversion = self .camera .revision
163+ _logger .info (" cam version " + self .camversion )
163164
164- #create img buffer to hold images.
165- #disable camera LED by default
165+ # create img buffer to hold images.
166+ # disable camera LED by default
166167 self .setLED (False )
167- self .set_awb_mode (0 ) # set auto white balance to off
168+ self .set_awb_mode (0 ) # set auto white balance to off
168169 self ._get_sensor_shape ()
169-
170-
170+
171171 def make_safe (self ):
172172 if self ._acquiring :
173173 self .abort ()
174-
174+
175175 def _do_disable (self ):
176176 self .abort ()
177177
178178 def _do_shutdown (self ):
179179 self ._do_disable ()
180180 self .camera .close ()
181-
181+
182182 def _do_enable (self ):
183183 _logger .info ("Preparing for acquisition." )
184184 if self ._acquiring :
185185 self .abort ()
186- #actually start camera
186+ # actually start camera
187187 if not self .camera :
188188 self .initialize ()
189189 self ._acquiring = True
190190 _logger .info ("Acquisition enabled." )
191191 return True
192192
193193 def abort (self ):
194- _logger .info (' Disabling acquisition.' )
194+ _logger .info (" Disabling acquisition." )
195195 if self ._acquiring :
196196 self ._acquiring = False
197-
198197
199- def set_trigger (self ,ttype : microscope .TriggerType ,
200- tmode : microscope .TriggerMode ) -> None :
198+ def set_trigger (
199+ self , ttype : microscope .TriggerType , tmode : microscope .TriggerMode
200+ ) -> None :
201201 if ttype == self ._trigger_type :
202202 return
203- elif ( ttype == microscope .TriggerType .SOFTWARE ) :
203+ elif ttype == microscope .TriggerType .SOFTWARE :
204204 GPIO .remove_event_detect (GPIO_Trigger )
205- self ._trigger_type = microscope .TriggerType .SOFTWARE
206- elif (ttype == microscope .TriggerType .RISING_EDGE ):
207- GPIO .add_event_detect (GPIO_Trigger ,GPIO .RISING ,
208- callback = self .HW_trigger ,
209- bouncetime = 10 )
210- self ._trigger_type = microscope .TriggerType .RISING_EDGE
211-
205+ self ._trigger_type = microscope .TriggerType .SOFTWARE
206+ elif ttype == microscope .TriggerType .RISING_EDGE :
207+ GPIO .add_event_detect (
208+ GPIO_Trigger ,
209+ GPIO .RISING ,
210+ callback = self .HW_trigger ,
211+ bouncetime = 10 ,
212+ )
213+ self ._trigger_type = microscope .TriggerType .RISING_EDGE
212214
213215 @property
214216 def trigger_mode (self ) -> microscope .TriggerMode :
215- # if self._trigger_type==devices.TRIGGER_BEFORE:
217+ # if self._trigger_type==devices.TRIGGER_BEFORE:
216218 return microscope .TriggerMode .ONCE
217- # else:
218- # return microscope.TriggerMode.ONCE
219+
220+ # else:
221+ # return microscope.TriggerMode.ONCE
219222
220223 @property
221224 def trigger_type (self ) -> microscope .TriggerType :
@@ -229,60 +232,57 @@ def _set_binning(self, h_bin, v_bin):
229232 return True
230233
231234 def _get_binning (self ):
232- return ( Binning (1 ,1 ) )
235+ return Binning (1 , 1 )
233236
234237 @keep_acquiring
235238 def _set_roi (self , left , top , width , height ):
236239 """Set the ROI to (left, tip, width, height)."""
237240 self .roi = ROI (left , top , width , height )
238-
239-
240- #set camera LED status, off is best for microscopy.
241+
242+ # set camera LED status, off is best for microscopy.
241243 def setLED (self , state = False ):
242244 GPIO .output (GPIO_CAMLED , state )
243245
244246 def set_exposure_time (self , value ):
245- #exposure times are set in us.
246- self .camera .shutter_speed = (int (value * 1.0E6 ))
247-
247+ # exposure times are set in us.
248+ self .camera .shutter_speed = int (value * 1.0e6 )
248249
249250 def get_exposure_time (self ):
250- #exposure times are in us, so multiple by 1E-6 to get seconds.
251- return (self .camera .exposure_speed * 1.0E-6 )
252-
251+ # exposure times are in us, so multiple by 1E-6 to get seconds.
252+ return self .camera .exposure_speed * 1.0e-6
253253
254254 def get_cycle_time (self ):
255- #fudge to make it work initially
256- #exposure times are in us, so multiple by 1E-6 to get seconds.
257- return ( self .camera .exposure_speed * 1.0E-6 + .1 )
255+ # fudge to make it work initially
256+ # exposure times are in us, so multiple by 1E-6 to get seconds.
257+ return self .camera .exposure_speed * 1.0e-6 + 0.1
258258
259-
260259 def _get_sensor_shape (self ):
261- if self .camversion == 'ov5647' : #picam version 1
262- self .camera .resolution = (2592 ,1944 )
263- #faqll back to defualt if not set above.
264- res = self .camera .resolution
265- self ._set_roi (0 ,0 ,res [0 ],res [1 ])
266- return (res )
260+ if self .camversion == "ov5647" : # picam version 1
261+ self .camera .resolution = (2592 , 1944 )
262+ # faqll back to defualt if not set above.
263+ res = self .camera .resolution
264+ self ._set_roi (0 , 0 , res [0 ], res [1 ])
265+ return res
266+
267267 def _do_trigger (self ):
268268 self .soft_trigger ()
269-
269+
270270 def soft_trigger (self ):
271- _logger .info ('Trigger received; self._acquiring is %s.'
272- % self ._acquiring )
271+ _logger .info (
272+ "Trigger received; self._acquiring is %s." % self ._acquiring
273+ )
273274 if self ._acquiring :
274275 with picamera .array .PiYUVArray (self .camera ) as output :
275- self .camera .capture (output , format = 'yuv' , use_video_port = False )
276- self ._queue .put (output .array [:,:,0 ])
277-
276+ self .camera .capture (output , format = "yuv" , use_video_port = False )
277+ self ._queue .put (output .array [:, :, 0 ])
278278
279279
280- #ongoing implemetation notes
280+ # ongoing implemetation notes
281281
282- #should be able to use rotation and hflip to set specific output image
282+ # should be able to use rotation and hflip to set specific output image
283283# rotations
284284
285- #roi's can be set with the zoom function, default is (0,0,1,1) meaning all the data.
285+ # roi's can be set with the zoom function, default is (0,0,1,1) meaning all the data.
286286
287- #Need to setup a buffer for harware triggered data aquisition so we can
288- #call the acquisition and then download the data at our leasure
287+ # Need to setup a buffer for harware triggered data aquisition so we can
288+ # call the acquisition and then download the data at our leasure
0 commit comments