@@ -44,7 +44,6 @@ class Microscope(Device, metaclass=CombinedMeta):
4444 # Device properties — configure in Tango DB per deployment
4545 # ------------------------------------------------------------------
4646
47-
4847 scan_device_address = device_property (
4948 dtype = str ,
5049 doc = "Tango device address for the SCAN settings device. "
@@ -66,14 +65,12 @@ class Microscope(Device, metaclass=CombinedMeta):
6665 "No-DB mode: 'tango://127.0.0.1:8888/test/nodb/stage#dbase=no'" ,
6766 )
6867
69-
70- corrector_device_address = device_property (
68+ camera_device_address = device_property (
7169 dtype = str ,
72- doc = "Tango device address for the aberration corrector settings device . "
73- "DB mode: 'test/hardware/corrector ' "
74- "No-DB mode: 'tango://127.0.0.1:8888/test/nodb/corrector #dbase=no'" ,
70+ doc = "Tango device address for the CAMERA settings . "
71+ "DB mode: 'test/detector/camera ' "
72+ "No-DB mode: 'tango://127.0.0.1:8888/test/nodb/camera #dbase=no'" ,
7573 )
76-
7774 testing_mode_bool = device_property (dtype = bool ,
7875 default_value = False ,
7976 doc = "When True - used for running tests, passed in conftest.py" )
@@ -198,6 +195,14 @@ def get_spectrum(self, detector_name: str) -> tuple[str, bytes]:
198195
199196 return json .dumps (metadata ), raw_bytes
200197
198+ @command (dtype_out = DevEncoded )
199+ def get_camera_image (self ) -> tuple [str , bytes ]:
200+ """
201+ get image on the camera
202+ """
203+
204+ camera = self ._detector_proxies .get ("camera" )
205+ # use this to get params
201206
202207 @command (dtype_out = DevEncoded )#In PyTango, DevEncoded is a special Tango data type designed to send binary data + a small description string together as a single return value.
203208 def get_scanned_image (self ) -> tuple [str , bytes ]:
@@ -224,18 +229,63 @@ def get_scanned_image(self) -> tuple[str, bytes]:
224229 dwell_time = scan .dwell_time
225230 imsize = scan .imsize
226231
227- adorned_image = self ._acquire_stem_image (imsize , dwell_time , ['haadf' ])
232+ image = self ._acquire_stem_image (imsize , dwell_time , ['haadf' ])
228233
229234 metadata = {
230235 "detector" : 'haadf' ,
231236 "shape" : [imsize , imsize ],
232- "dtype" : str (adorned_image .dtype ),
237+ "dtype" : str (image .dtype ),
233238 "dwell_time" : dwell_time ,
234239 "timestamp" : time .time (),
235240 # TODO: add metadata from adorned_image.metadata when using real AutoScript
236241 }
237242
238- return json .dumps (metadata ), adorned_image .tobytes ()
243+ return json .dumps (metadata ), image .tobytes ()
244+
245+
246+ @command (dtype_out = DevEncoded )
247+ def get_camera_image (self ) -> tuple [str , bytes ]:
248+ """
249+ Acquire a single camera image from the named detector.
250+
251+ Parameters
252+ ----------
253+ detector_name:
254+ Name of the detector, e.g. "BM-Ceta". Must match a key in
255+ self._detector_proxies.
256+
257+ Returns
258+ -------
259+ DevEncoded = (json_metadata, raw_bytes)
260+ json_metadata includes: shape, dtype, dwell_time, detector,
261+ timestamp, and any other relevant metadata.
262+ raw_bytes is the flat numpy array bytes; reshape using shape from metadata.
263+ """
264+
265+ # check active detectors
266+ camera = self ._detector_proxies .get ("camera" )
267+
268+ # Read settings from the detector
269+ exposure_time = camera .exposure_time
270+ imsize = camera .imsize
271+ readout_area = camera .readout_area
272+
273+ image = self ._acquire_camera_image (imsize = imsize , exposure_time = exposure_time ,
274+ detector = 'BM-Ceta' , readout_area = readout_area )
275+
276+ metadata = {
277+ "detector" : 'Ceta' ,
278+ "shape" : [imsize , imsize ],
279+ "dtype" : str (image .dtype ),
280+ "exposure_time" : exposure_time ,
281+ "timestamp" : time .time (),
282+ "readout_area" : readout_area ,
283+ # TODO: move this metadata packing into the _acquire_camera_image method
284+ # when usingreal AutoScript,to include metadata from adorned_image.metadata
285+ }
286+
287+ return json .dumps (metadata ), image .tobytes ()
288+
239289
240290 @command (dtype_in = ('str' ,), dtype_out = str )
241291 def get_images (self , detector_names : list [str ]) -> str :
@@ -328,11 +378,32 @@ def unblank_beam(self) -> None:
328378 @command (dtype_in = DevFloat )
329379 def set_fov (self , fov ):
330380 """
331- set the field of view for the next acquisition, [0:1]
381+ set the field of view for the next acquisition
332382 """
333383 print (fov )
334384 self ._set_fov (fov )
335385
386+ @command (dtype_out = DevFloat )
387+ def get_fov (self ):
388+ """
389+ read the field of view for the next acquisition
390+ """
391+ return self ._get_fov ()
392+
393+ @command (dtype_in = DevFloat )
394+ def set_screen_current (self , current ):
395+ """
396+ set the screen current in pA
397+ """
398+ self ._set_screen_current (current )
399+
400+ @command (dtype_out = DevFloat )
401+ def get_screen_current (self ):
402+ """
403+ get the screen current in pA
404+ """
405+ return self ._get_screen_current ()
406+
336407 @command (dtype_out = DevVarFloatArray )
337408 def get_stage (self ):
338409 """
@@ -359,6 +430,23 @@ def move_stage(self, position):
359430 """
360431 self ._move_stage (position )
361432
433+ @command ()
434+ def auto_focus (self ):
435+ """
436+ Run the microscope's autofocus routine.
437+ """
438+ self ._auto_focus ()
439+
440+ @command (dtype_in = DevVarFloatArray )
441+ def set_image_shift (self , shift ):
442+ """
443+ Set the image shift to the specified values [x_shift, y_shift].
444+
445+ Parameters
446+ ----------
447+ shift: list of two floats [x_shift, y_shift] specifying the desired image shift in meters.
448+ """
449+ self ._set_image_shift (shift )
362450 # ------------------------------------------------------------------
363451 # Internal acquisition helpers
364452 # ------------------------------------------------------------------
@@ -371,6 +459,9 @@ def _acquire_stem_image():
371459 def _acquire_stem_image_advanced ():
372460 print ("Get image with more flexible settings" )
373461 pass
462+ def _acquire_camera_image ():
463+ # define in the inherit class
464+ pass
374465
375466 def _place_beam ():
376467 # define in the inherit class
@@ -384,6 +475,15 @@ def _unblank_beam():
384475 # define in the inherit class
385476 pass
386477
478+ @abstractmethod
479+ def _set_screen_current ():
480+ # define in the inherit class
481+ pass
482+
483+ @abstractmethod
484+ def _get_screen_current ():
485+ pass
486+
387487 @abstractmethod
388488 def _move_stage ():
389489 # define in the inherit class
@@ -396,6 +496,18 @@ def _get_stage():
396496 @abstractmethod
397497 def _set_fov ():
398498 pass
499+
500+ @abstractmethod
501+ def _get_fov ():
502+ pass
503+
504+ @abstractmethod
505+ def _auto_focus ():
506+ pass
507+
508+ @abstractmethod
509+ def _set_image_shift ():
510+ pass
399511# ----------------------------------------------------------------------
400512# Server entry point
401513# ----------------------------------------------------------------------
0 commit comments