diff --git a/DCAMCamera/blacs_workers.py b/DCAMCamera/blacs_workers.py index 923a602e890cbebb7799a4296204ea7ff2acf271..03bacb39cf5631a3dcd876a617cbccdc599cf8ea 100644 --- a/DCAMCamera/blacs_workers.py +++ b/DCAMCamera/blacs_workers.py @@ -7,10 +7,6 @@ # # ##################################################################### -import numpy as np -from labscript_utils import dedent -from enum import IntEnum - from labscript_devices.IMAQdxCamera.blacs_workers import IMAQdxCameraWorker # Don't import API yet so as not to throw an error, allow worker to run as a dummy @@ -26,17 +22,9 @@ class DCAM_Camera(object): (i.e. transition_to_buffered, get_attributes, snap, etc). Attributes: + propList (dict): Dictionary with property names and keys. + timeout (int): Timeout in ms camera (dcamAPI.Dcam): Handle to connected camera. - get_props (list): This list sets which values of each property object - are returned when queried by :obj:`get_attribute`. - pixel_formats (IntEnum): An IntEnum object that is automatically - populated with the supported pixel types of the connected camera. - width (int): Width of images for most recent acquisition. - Used by :obj:`_decode_image_data` to format images correctly. - height (int): Height of images for most recent acquisition. - Used by :obj:`_decode_image_data` to format images correctly. - pixelFormat (str): Pixel format name for most recent acquisition. - Used by :obj:`_decode_image_data` to format images correctly. _abort_acquisition (bool): Abort flag that is polled during buffered acquisitions. """ @@ -52,9 +40,9 @@ class DCAM_Camera(object): This function also does a significant amount of default configuration. Args: - serial_number (str): serial number of camera to connect to + serial_number (int): serial number of camera to connect to """ - self.timeout = 60000 + self.timeout = 5000 global dcamAPI import user_devices.DCAMCamera.dcam as dcamAPI @@ -65,7 +53,7 @@ class DCAM_Camera(object): dcamAPI.Dcamapi.uninit() raise RuntimeError(msg) - print('Connecting to S/N: %s ...'%serial_number) + print(f'Connecting to S/N: {serial_number:06x} ...') #Iterate Trough Cameras for camID in range(dcamAPI.Dcamapi.get_devicecount()): self.camera = dcamAPI.Dcam(camID) @@ -106,7 +94,6 @@ class DCAM_Camera(object): Args: attr_dict (dict): dictionary of property dictionaries to set for the camera. """ - print(attr_dict) for attr, value in attr_dict.items(): propID = self.propList[attr] self.camera.prop_setvalue(propID,value) @@ -154,8 +141,6 @@ class DCAM_Camera(object): Returns: numpy.array: Acquired image """ - self.camera - self.configure_acquisition(continuous=False,bufferCount=1) self.camera.cap_snapshot() @@ -176,8 +161,6 @@ class DCAM_Camera(object): def configure_acquisition(self, continuous=True, bufferCount=10): """Configure acquisition buffer count and grab mode. - This method also saves image width, heigh, and pixelFormat to class - attributes for returned image formatting. Args: continuous (:obj:`bool`, optional): If True, camera will continuously @@ -194,26 +177,27 @@ class DCAM_Camera(object): msg='Dcam.buf_alloc() fails with error {}'.format(dcamAPI.DCAMERR(dcamAPI.Dcamapi.lasterr()).name) raise RuntimeError(msg) - self.width = self.camera.prop_getvalue(dcamAPI.DCAM_IDPROP.IMAGE_WIDTH) - self.height = self.camera.prop_getvalue(dcamAPI.DCAM_IDPROP.IMAGE_HEIGHT) - self.pixelFormat = self.camera.prop_getvaluetext(dcamAPI.DCAM_IDPROP.IMAGE_PIXELTYPE,self.camera.prop_getvalue(dcamAPI.DCAM_IDPROP.IMAGE_PIXELTYPE)) - if continuous: - self.camera.cap_start(True) + # Start acquisition + # if continuous or bufferCount>1: + self.camera.cap_start() - def grab(self): + def grab(self,bufferNo=-1): """Grab and return single image during pre-configured acquisition. + Args: + bufferNo (int): number of image in buffer. + If bufferNo=-1 (default), the function call of + buf_getframedata() is equal to buf_getlastframedata() + Returns: numpy.array: Returns formatted image """ - if(self.camera.cap_status()==dcamAPI.DCAMCAP_STATUS.READY): - self.camera.cap_start() - if self.camera.wait_capevent_frameready(self.timeout) is not False: - image = self.camera.buf_getlastframedata() + if self.camera.wait_capevent_frameready(self.timeout): + image = self.camera.buf_getframedata(bufferNo) else: dcamerr = dcamAPI.Dcamapi.lasterr() if dcamerr.is_timeout(): - print('===: timeout') + raise RuntimeError('===: timeout') else: msg='Dcam.wait() fails with error {}'.format(dcamAPI.DCAMERR(dcamerr).name) raise RuntimeError(msg) @@ -237,8 +221,8 @@ class DCAM_Camera(object): print("Abort during acquisition.") self._abort_acquisition = False return - images.append(self.grab()) - print(f"Got image {i+1} of {n_images}.") + images.append(self.grab(bufferNo=i)) + print(f"Got image {i+1} of {n_images}.") print(f"Got {len(images)} of {n_images} images.") @@ -258,10 +242,10 @@ class DCAM_Camera(object): dcamAPI.Dcamapi.uninit() class DCAMCameraWorker(IMAQdxCameraWorker): - """FlyCapture2 API Camera Worker. + """DCAMCameraWorker API Camera Worker. Inherits from obj:`IMAQdxCameraWorker`. Defines :obj:`interface_class` and overloads - :obj:`get_attributes_as_dict` to use FlyCapture2Camera.get_attributes() method.""" + :obj:`get_attributes_as_dict` to use DCAMCameraWorker.get_attributes() method.""" interface_class = DCAM_Camera def get_attributes_as_dict(self, visibility_level): diff --git a/TimeBaseAOMDriver/blacs_workers.py b/TimeBaseAOMDriver/blacs_workers.py index f6f0265ef268d6f2cbd03a40dca2a0658eedd11b..bc54d821e7e31d34645f6ec8edee3a14e36786d8 100644 --- a/TimeBaseAOMDriver/blacs_workers.py +++ b/TimeBaseAOMDriver/blacs_workers.py @@ -34,13 +34,13 @@ class TimeBaseWorker(Worker): group = file[f"devices/{device_name}"] for channel in group: for attr,value in group[channel].attrs.items(): - if self.smart_cache[channel][attr] != group[channel].attrs[attr] or fresh: + if self.smart_cache[channel].get(attr) != group[channel].attrs[attr] or fresh: # Disable sweep mode, if it was in use. # This is necessary is update the sweep mode parameters. - if self.smart_cache["Sswpm"] != 0: + if self.smart_cache[channel].get("Sswpm") != 0: print(f"Programming {channel}, Sswpm=0") self.client.send(f"{channel}|Sswpm:0\r\n".encode()) - self.smart_cache["Sswpm"] = 0 + self.smart_cache[channel]["Sswpm"] = 0 time.sleep(0.01) if attr == "Sswpm": # Skip sweep mode, becasue I want to enable it only after @@ -51,10 +51,10 @@ class TimeBaseWorker(Worker): self.smart_cache[channel][attr] = group[channel].attrs[attr] time.sleep(0.01) # TODO: What's the best time here? Do we need to wait at all? According to the DIM-3000 manual the rate is 10 commands per second, it seems router can also handle faster times? # Program actual value of sweep mode - if group[channel]["Sswpm"] != 0: + if group[channel].attrs["Sswpm"] != 0: print(f"Programming {channel}, Sswpm") - self.client.send(f"{channel}|Sswpm:{group[channel]['Sswpm']}\r\n".encode()) - self.smart_cache["Sswpm"] = {group[channel]['Sswpm']} + self.client.send(f"{channel}|Sswpm:{group[channel].attrs['Sswpm']}\r\n".encode()) + self.smart_cache[channel]["Sswpm"] = {group[channel].attrs['Sswpm']} time.sleep(0.01) if not initial_values[channel]["gate"]: diff --git a/TimeBaseAOMDriver/labscript_devices.py b/TimeBaseAOMDriver/labscript_devices.py index 353201220c9b6bb6c37c33185739069282e8b8a7..72878506587e35826041692c860ccf63642de3ba 100644 --- a/TimeBaseAOMDriver/labscript_devices.py +++ b/TimeBaseAOMDriver/labscript_devices.py @@ -71,7 +71,8 @@ class TimeBaseAOM(Device): """ if value not in self.parent_device.FM_deviations: raise LabscriptError(f"FM devivation of {self.name} is none of the allowed values.") - self.FM_deviation.constant(value) + set_value = int(np.round(np.log2(value/3200))) + self.FM_deviation.constant(set_value) @@ -158,6 +159,8 @@ class TimeBaseAOMDriver(Device): if command=="Sampl": # Amplitude has to be programmed in 0.1*dBm AOM_group.attrs[command] = np.round(10*output.static_value).astype(np.int32) + AOM_group.attrs["Sfampl"] =np.round(10*output.static_value).astype(np.int32) + else: AOM_group.attrs[command] = np.round(output.static_value).astype(np.int32)