From 2d3b800d11fc36ebf40f3e2b4460ca5401f0117a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 24 Mar 2017 16:00:06 +0100 Subject: [PATCH 1/4] Fix: zi ensure single trigger mode is always set This get reset when enabling the read --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 1f78667d953a..41d04faea960 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -390,6 +390,13 @@ def get(self): params['scope_runstop'].set('run') log.info('[*] Starting ZI scope acquisition.') + # one shot per trigger. This needs to be set every time + # a the scope is enabled as below using scope_runstop + # We should also test if scopeModule/mode and scopeModule/averager/weight + # needs to be set every time since we are creating a new scopemodule + # here + self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) + self._instrument.daq.sync() # Start something... hauling data from the scopeModule? scope.execute() From 2702b739b6b4b4a4a378921cec4acd557d10b318 Mon Sep 17 00:00:00 2001 From: jana-d Date: Fri, 24 Mar 2017 17:05:55 +0100 Subject: [PATCH 2/4] fix move trigger mode setting to where it belongs --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 41d04faea960..40f9d61fd256 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -379,7 +379,13 @@ def get(self): # We add one second to account for latencies and random delays meas_time = segs*(params['scope_duration'].get()+deadtime)+1 npts = params['scope_length'].get() - + # one shot per trigger. This needs to be set every time + # a the scope is enabled as below using scope_runstop + # We should also test if scopeModule/mode and scopeModule/averager/weight + # needs to be set every time since we are creating a new scopemodule + # here + self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) + self._instrument.daq.sync() # Create a new scopeModule instance (TODO: Why a new instance?) scope = self._instrument.daq.scopeModule() @@ -390,13 +396,7 @@ def get(self): params['scope_runstop'].set('run') log.info('[*] Starting ZI scope acquisition.') - # one shot per trigger. This needs to be set every time - # a the scope is enabled as below using scope_runstop - # We should also test if scopeModule/mode and scopeModule/averager/weight - # needs to be set every time since we are creating a new scopemodule - # here - self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) - self._instrument.daq.sync() + # Start something... hauling data from the scopeModule? scope.execute() From 38eb0e9519f251e5cbf565f099b2cb79672b25aa Mon Sep 17 00:00:00 2001 From: jana-d Date: Tue, 28 Mar 2017 16:38:38 +0200 Subject: [PATCH 3/4] Fix: zi reuse scope and handle errors by retrying --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 104 +++++++++++++----------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 40f9d61fd256..0aaab5147334 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -1,4 +1,4 @@ -import time +port time import logging import numpy as np from functools import partial @@ -379,53 +379,61 @@ def get(self): # We add one second to account for latencies and random delays meas_time = segs*(params['scope_duration'].get()+deadtime)+1 npts = params['scope_length'].get() - # one shot per trigger. This needs to be set every time - # a the scope is enabled as below using scope_runstop - # We should also test if scopeModule/mode and scopeModule/averager/weight - # needs to be set every time since we are creating a new scopemodule - # here - self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) - self._instrument.daq.sync() - # Create a new scopeModule instance (TODO: Why a new instance?) - scope = self._instrument.daq.scopeModule() - - # Subscribe to the relevant... publisher? - scope.subscribe('/{}/scopes/0/wave'.format(self._instrument.device)) - - # Start the scope triggering/acquiring - params['scope_runstop'].set('run') - - log.info('[*] Starting ZI scope acquisition.') - - # Start something... hauling data from the scopeModule? - scope.execute() - starttime = time.time() + zi_error = True + error_counter = 0 + num_retries = 10 timedout = False - - while scope.progress() < 1: - time.sleep(0.1) # This while+sleep is how ZI engineers do it - if (time.time()-starttime) > meas_time: - scope.finish() # Force break the acquisition - timedout = True - log.warning('[-] ZI Scope acquisition did not finish correctly') - break - - # Stop the scope from running - params['scope_runstop'].set('stop') - - if not timedout: - log.info('[+] ZI scope acquisition completed OK') - rawdata = scope.read() - data = self._scopedataparser(rawdata, self._instrument.device, - npts, segs, channels) - else: - rawdata = None - data = (None, None) - - # kill the scope instance - scope.clear() - + while (zi_error or timedout) and error_counter < num_retries: + # one shot per trigger. This needs to be set every time + # a the scope is enabled as below using scope_runstop + self._instrument.daq.setInt('/{}/scopes/0/single'.format(self._instrument.device), 1) + self._instrument.daq.sync() + + scope = self._instrument.scope # There are issues reusing the scope. + + # Subscribe to the relevant... publisher? + scope.subscribe('/{}/scopes/0/wave'.format(self._instrument.device)) + + # Start the scope triggering/acquiring + params['scope_runstop'].set('run') # set /dev/scopes/0/enable to 1 + + log.info('[*] Starting ZI scope acquisition.') + # Start something... hauling data from the scopeModule? + scope.execute() + starttime = time.time() + timedout = False + + while scope.progress() < 1: + time.sleep(0.1) # This while+sleep is how ZI engineers do it + if (time.time()-starttime) > 2 * meas_time: + timedout = True + break + metadata = scope.get("scopeModule/*") + zi_error = bool(metadata['error'][0]) + + # Stop the scope from running + params['scope_runstop'].set('stop') + + if not (timedout or zi_error): + log.info('[+] ZI scope acquisition completed OK') + rawdata = scope.read() + data = self._scopedataparser(rawdata, self._instrument.device, + npts, segs, channels) + else: + log.warning('[-] ZI scope acquisition attempt {} ' + 'failed, Timeout: {}, Error: {}, ' + 'retrying'.format(error_counter, timedout, zi_error)) + rawdata = None + data = (None, None) + error_counter += 1 + + # cleanup and make ready for next scope acquisition + scope.finish() + scope.unsubscribe('/{}/scopes/0/wave'.format(self._instrument.device)) + if error_counter >= num_retries: + log.warning('[+] ZI scope acquisition failed, maximum number' + 'of retries performed. No data returned') return data @staticmethod @@ -1078,7 +1086,7 @@ def __init__(self, name, device_ID, **kwargs): vals=vals.Enum(1, 2, 3) ) - self._samplingrate_codes = {'1.80 Ghz': 0, + self._samplingrate_codes = {'1.80 GHz': 0, '900 MHz': 1, '450 MHz': 2, '225 MHz': 3, @@ -1933,5 +1941,7 @@ def close(self): """ Override of the base class' close function """ + self.scope.clear() + self.sweeper.clear() self.daq.disconnect() super().close() From 94cc47616fea4f725ed11ec8de3bc9373fe44c27 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 29 Mar 2017 10:34:50 +0200 Subject: [PATCH 4/4] Fix: typo --- qcodes/instrument_drivers/ZI/ZIUHFLI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/ZI/ZIUHFLI.py b/qcodes/instrument_drivers/ZI/ZIUHFLI.py index 0aaab5147334..e2e612947a3e 100644 --- a/qcodes/instrument_drivers/ZI/ZIUHFLI.py +++ b/qcodes/instrument_drivers/ZI/ZIUHFLI.py @@ -1,4 +1,4 @@ -port time +import time import logging import numpy as np from functools import partial