diff --git a/ADwinProII/ADwin_utils.py b/ADwinProII/ADwin_utils.py index fa1d2f41eaf3f9d62313bb05577763dec6f206d9..3ac371ebdba10f36f39344e18adb44fca772e7e1 100644 --- a/ADwinProII/ADwin_utils.py +++ b/ADwinProII/ADwin_utils.py @@ -156,7 +156,11 @@ def get_ain_traces(h5file, raw_data_name="ADwinAnalogIn_DATA", convert_data=True times = np.arange(acquisition_times["start_time"][i],acquisition_times["stop_time"][i],int(clock_rate//acquisition_times["storage_rate"][i])) / clock_rate else: times = np.arange(acquisition_times["start_time"][i],acquisition_times["stop_time"][i]) / clock_rate - # print(times.size,acquisition.size) + if "waits" in f["data"]: + # There was a wait in the experiment, let's offset the times such that they are accurate + waits = f["data/waits"][:] + for i in range(len(waits)): + times[times > waits["time"][i]] += waits["duration"][i] if write_hdf5: data = np.rec.fromarrays([times, acquisition], dtype=dtype) group.create_dataset(label, compression = config.compression, data = data) diff --git a/ADwinProII/blacs_workers.py b/ADwinProII/blacs_workers.py index c2db3c2ee7ed954cb08d42f6a2964c08110c8c38..bf67faa5b999c60626f58f3b2bbb8527a226f508 100644 --- a/ADwinProII/blacs_workers.py +++ b/ADwinProII/blacs_workers.py @@ -142,6 +142,9 @@ class ADwinProIIWorker(Worker): self.stop_time = group.attrs["stop_time"] # Send stop time to ADwin self.adw.Set_Par(2, int(self.stop_time * CLOCK_T12 / self.PROCESSDELAY)) + # Send wait time and timeout to ADwin (default 0 if no waits) + self.adw.Set_Par(3, group.attrs.get("wait_time",0)) + self.adw.Set_Par(5, group.attrs.get("wait_timeout",0)) # Send data to ADwin AOUT = group["ANALOG_OUT/VALUES"] if fresh or not np.array_equal(AOUT[:],self.smart_cache["AOUT"]): @@ -157,6 +160,7 @@ class ADwinProIIWorker(Worker): self.smart_cache[name] = DOUT[:] self.adw.SetData_Long(DOUT["n_cycles"], module, 1, DOUT.shape[0]) self.adw.SetData_Long(DOUT["bitfield"], module+1, 1, DOUT.shape[0]) + self.adw.Set_Par(module-1, DOUT.attrs.get("wait_time",0)) PIDs = group["ANALOG_OUT/PID_CHANNELS"] if fresh or not np.array_equal(PIDs[:],self.smart_cache["PIDs"]): print("PIDs programmed.") @@ -207,6 +211,19 @@ class ADwinProIIWorker(Worker): # array["values"] = workload_data # group.create_dataset("ADwin_Workload", compression = config.compression, data = array) # f['devices/ADwin/ANALOG_IN'].attrs["ADwin_Workload"] = "TEST" + + # Get wait duration + if f[f"devices/{self.device_name}"].attrs.get("wait_time", None) is not None: + wait_duration = self.adw.Get_Par(4) / CLOCK_T12 * self.PROCESSDELAY + wait_table = f["waits"] + dtypes = [('label', 'a256'),('time', float),('timeout', float),('duration', float),('timed_out', bool)] + data = np.empty(len(wait_table), dtype=dtypes) + data['label'] = wait_table['label'] + data['time'] = wait_table['time'] + data['timeout'] = wait_table['timeout'] + data['duration'] = wait_duration + data['timed_out'] = wait_duration > wait_table['timeout'] + f.create_dataset('/data/waits', data=data) # Delete h5file from worker, shot is finished self.h5file = None # Check if the TiCo processes were running correctly diff --git a/ADwinProII/labscript_devices.py b/ADwinProII/labscript_devices.py index f74a85b4056302be67bca20f1bfae9040378ece7..c727013794f06926f9b623995f755beff20169df 100644 --- a/ADwinProII/labscript_devices.py +++ b/ADwinProII/labscript_devices.py @@ -14,7 +14,7 @@ ############################################################################ -from labscript import Pseudoclock, PseudoclockDevice, ClockLine, Device, LabscriptError, config, set_passed_properties +from labscript import Pseudoclock, PseudoclockDevice, ClockLine, Device, LabscriptError, config, set_passed_properties, compiler import numpy as np from . import PROCESSDELAY_T12, PROCESSDELAY_TiCo, CLOCK_T12, CLOCK_TiCo, MAX_EVENTS, MAX_PID_EVENTS, A_IN_BUFFER @@ -198,8 +198,8 @@ class ADwinProII(PseudoclockDevice): def do_checks(self, outputs): - if self.trigger_times != [0]: - raise NotImplementedError('ADwin does not support retriggering or waiting.') + if len(self.trigger_times)>2 or self.trigger_times[1] not in compiler.wait_table: + raise NotImplementedError('ADwin does not support retriggering, and only supports one "wait" in the current implementation.') for output in outputs: output.do_checks(self.trigger_times) @@ -242,6 +242,8 @@ class ADwinProII(PseudoclockDevice): PID_config.append(device.PID_config) elif isinstance(device,ADwinDIO32): group.create_dataset("DIGITAL_OUT/"+device.name, data=device.digital_data) + if compiler.wait_table: + group["DIGITAL_OUT/"+device.name].attrs["wait_time"] = round( list(compiler.wait_table)[0] * device.parent_clock_line.clock_limit ) elif isinstance(device,ADwinAI8): # For the AIN table it's required that self.modules is sorted correctly! analog_input.append(device.AIN_times) @@ -312,4 +314,13 @@ class ADwinProII(PseudoclockDevice): # Save list of module names to connection table properties module_dict = {str(module.module_address) : module.name for module in self.modules} self.set_property("modules", module_dict, "connection_table_properties") + + # Add wait time and timeout in units of ADwin process cycles + if len(compiler.wait_table)>1: + raise LabscriptError("ADwin supports only a sinlge wait for now!") + for time,args in compiler.wait_table.items(): + hdf5_file[f"devices/{self.name}"].attrs["wait_time"] = round(time * self._pseudoclock_T12.clock_limit) + hdf5_file[f"devices/{self.name}"].attrs["wait_timeout"] = round(args[1] * self._pseudoclock_T12.clock_limit) + for TiCo in self.TiCos: + hdf5_file[f"devices/{self.name}/DIGITAL_OUT/"].attrs["wait_time"] = round(time * self._pseudoclock_T12.clock_limit) \ No newline at end of file