From f5a28a0c00cae603d7a7b897f4b7ce8a6a1dc012 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 13 Jun 2018 10:59:25 +0200 Subject: [PATCH 001/719] basic adapter, packing is missing --- .../instrument_drivers/tektronix/AWG5014.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index b5988b68769..32eadb91a6f 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1022,6 +1022,45 @@ def mrkdeltrans(x): return AWG_channel_cfg + def generate_awg_file_from_forged_sequence(self, seq): + # TODO: create channel_cfg, sequence_cfg, preservechannelsettings + packed_waveforms = {} + # unfortunately the definitions of the sequence elements in terms of channel and step in `generate_awg_file` and the forged sequence definition are transposed. Start by filling out after schema and transpose at the end + wfname_l = [] + nrep = [] + trig_wait = [] + goto_state = [] + jump_to = [] + for step, elem in seq.items(): + assert elem['type'] == 'element' + content = elem['content'] + assert len(content.keys()) == 1 + # get first element + # this seems very complicated but is probably necessary + # one could use pop, but this would change the content + content = content[list(content.keys())[0]] + + # waveform data + datadict = content['data'] + step_waveform_names = [] + for channel_name, data in datadict.items(): + waveform_name = f'Step{step}_Channel{channel_name}' + packed_waveforms[waveform_name] = data + step_waveform_names.append(waveform_name) + wfname_l.append(step_waveform_names) + + # sequencing + seq_opts = elem['sequencing'] + nrep.append(seq_opts.get('nrep', 1)) + trig_wait.append(seq_opts.get('trig_wait', 0)) + goto_state.append(seq_opts.get('goto_state',0)) + jump_to.append(seq_opts.get('jump_to', 0)) + # transpose list of lists + wfname_l = [list(x) for x in zip(*wfname_l)] + channel_cfg = {} + self.generate_awg_file(packed_waveforms, wfname_l, nrep, trig_wait, + goto_state, jump_to, channel_cfg) + def generate_awg_file(self, packed_waveforms, wfname_l, nrep, trig_wait, goto_state, jump_to, channel_cfg, From bc65f6486000d12cbbcd801e14f00e1f2cc630f4 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 20 Jun 2018 10:08:16 +0200 Subject: [PATCH 002/719] first working version --- .../instrument_drivers/tektronix/AWG5014.py | 127 ++++++++++++++---- 1 file changed, 98 insertions(+), 29 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 32eadb91a6f..395057bbf67 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1,6 +1,7 @@ import struct import logging import warnings +import re import numpy as np import array as arr @@ -1022,45 +1023,113 @@ def mrkdeltrans(x): return AWG_channel_cfg - def generate_awg_file_from_forged_sequence(self, seq): - # TODO: create channel_cfg, sequence_cfg, preservechannelsettings - packed_waveforms = {} - # unfortunately the definitions of the sequence elements in terms of channel and step in `generate_awg_file` and the forged sequence definition are transposed. Start by filling out after schema and transpose at the end - wfname_l = [] - nrep = [] - trig_wait = [] - goto_state = [] - jump_to = [] + + # def make_awg_file_from_forged_sequence(self, seq, channel_mapping: Dict[Union[str, int], Union[int, str]], + def make_awg_file_from_forged_sequence(self, seq, channel_mapping, + filename='customawgfile.awg', preservechannelsettings=True): + """ + Makes an awg file form a forged sequence as produced by broadbean.sequence.Sequence.forge. The forged sequence is a dictionary (see broadbean.sequence.fs_schmema) that does not need to be created by broadbean. + + Args: + seq: the sequence dictionary + + channel_mapping: a dictionary that maps the abstract channel id as assigned (e.g. in broadbean) to a physical channel of the device. For this particular device the channels are integers starting at TODO: 1?. Unmapped channels will be ignored, so that one can create forged sequences accross several instruments. + filename: filename of the uploaded awg file. See :meth:`~make_send_and_load_awg_file` + preservechannelsettings: see :meth:`~make_send_and_load_awg_file` + + """ + n_channels = 4 + self.available_signal_channels = list(range(1,n_channels+1)) + self.available_marker_channels = [f'{m}M{c}' + for c in self.available_signal_channels + for m in [1,2]] + self.available_channels = self.available_signal_channels + self.available_marker_channels + + waveforms = [] + m1s = [] + m2s = [] + # unfortunately the definitions of the sequence elements in terms of channel and step in :meth:`make_and_send_awg_file` and the forged sequence definition are transposed. Start by filling out after schema and transpose at the end + # make...: [[wfm1ch1, wfm2ch1, ...], [wfm1ch2, wfm2ch2], ...] + # dict efectively: {elementid: {channelid: wfm}} + physical_channels = [] + + nreps = [] + trig_waits = [] + goto_states = [] + jump_tos = [] + + first_step = True for step, elem in seq.items(): + # TODO: add support for subsequences assert elem['type'] == 'element' content = elem['content'] assert len(content.keys()) == 1 - # get first element - # this seems very complicated but is probably necessary - # one could use pop, but this would change the content - content = content[list(content.keys())[0]] - + # there is only one element int the dict with key `1` in case of type == element + # and no sequencing information, i.e. there is only one entry with key 'data' # waveform data - datadict = content['data'] - step_waveform_names = [] - for channel_name, data in datadict.items(): - waveform_name = f'Step{step}_Channel{channel_name}' - packed_waveforms[waveform_name] = data - step_waveform_names.append(waveform_name) - wfname_l.append(step_waveform_names) - + datadict = content[1]['data'] + + # obtain list of channels defined in the first step + if first_step: + mapped_channels = [channel_mapping.get(k, None) for k in datadict.keys()] + # filter out all channels that are not relevant for this instrument + physical_channels = [v for v in mapped_channels if v in self.available_signal_channels] + first_step = False + + # create empty list with size of number of used channels + step_waveforms = [None] * len(physical_channels) + step_marker = [[None] * n_channels] * 2 + for channel_id, data in datadict.items(): + physical_channel = channel_mapping.get(channel_id, None) + + if physical_channel in self.available_marker_channels: + res = re.match('^(?P\d+)M(?P\d+)$', + physical_channel) + assert res is not None + step_marker[int(res.group('marker'))-1][int(res.group('channel'))-1] = data + elif physical_channel in self.available_signal_channels: + # treat the first step differently: here the channel order is defined + try: + index = physical_channels.index(physical_channel) + except IndexError: + #TODO: write error message + raise + step_waveforms[index] = data + else: + # only proceed if the defined channel is available on the instrument + # TODO: this needs some extra information in case we are using two instruments with the same channel names + # e.g. always add a prefix with the instrument name. + continue + + if any(x is None for x in step_waveforms): + # TODO: error message + raise RuntimeError + #TODO: make more general such that one can create a sequence without signals but only markers + n_samples = len(step_waveforms[0]) + for j in range(n_channels): + for i in range(2): + if step_marker[i][j] is None: + step_marker[i][j] = np.zeros(n_samples) + waveforms.append(step_waveforms) + m1s.append(step_marker[0]) + m2s.append(step_marker[1]) # sequencing seq_opts = elem['sequencing'] - nrep.append(seq_opts.get('nrep', 1)) - trig_wait.append(seq_opts.get('trig_wait', 0)) - goto_state.append(seq_opts.get('goto_state',0)) - jump_to.append(seq_opts.get('jump_to', 0)) + nreps.append(seq_opts.get('nrep', 1)) + trig_waits.append(seq_opts.get('trig_wait', 0)) + goto_states.append(seq_opts.get('goto_state',0)) + jump_tos.append(seq_opts.get('jump_to', 0)) # transpose list of lists - wfname_l = [list(x) for x in zip(*wfname_l)] + waveforms = [list(x) for x in zip(*waveforms)] channel_cfg = {} - self.generate_awg_file(packed_waveforms, wfname_l, nrep, trig_wait, - goto_state, jump_to, channel_cfg) + + self.make_send_and_load_awg_file(waveforms, m1s, m2s, + nreps, trig_waits, + goto_states, jump_tos, + channels=physical_channels, + filename=filename, + preservechannelsettings=preservechannelsettings) def generate_awg_file(self, packed_waveforms, wfname_l, nrep, trig_wait, goto_state, jump_to, channel_cfg, From 687b213ddf2b66090c85ff5ae138ee2536035495 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 26 Jun 2018 15:46:53 +0200 Subject: [PATCH 003/719] cosmetics --- .../instrument_drivers/tektronix/AWG5014.py | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 395057bbf67..4e0c1d2ca05 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1024,17 +1024,27 @@ def mrkdeltrans(x): return AWG_channel_cfg - # def make_awg_file_from_forged_sequence(self, seq, channel_mapping: Dict[Union[str, int], Union[int, str]], - def make_awg_file_from_forged_sequence(self, seq, channel_mapping, - filename='customawgfile.awg', preservechannelsettings=True): + def parse_marker_channel_name(name:str)->Tupel[int, int]: """ - Makes an awg file form a forged sequence as produced by broadbean.sequence.Sequence.forge. The forged sequence is a dictionary (see broadbean.sequence.fs_schmema) that does not need to be created by broadbean. + returns from the channel index and marker index from a marker descriptor string e.g. '1M1'->(1,1) + """ + res = re.match('^(?P\d+)M(?P\d+)$', + name) + assert res is not None + MarkerDescriptor = namedtuple('MarkerDescriptor', 'marker', 'channel') + return MarkerDescriptor(int(res.group('marker')), int(res.group('channel'))) + + def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', preservechannelsettings=True): + """ + Makes an awg file form a forged sequence as produced by + broadbean.sequence.Sequence.forge. The forged sequence is a dictionary + (see :attr:`fs_schmea `) that does not + need to be created by broadbean. Args: seq: the sequence dictionary - - channel_mapping: a dictionary that maps the abstract channel id as assigned (e.g. in broadbean) to a physical channel of the device. For this particular device the channels are integers starting at TODO: 1?. Unmapped channels will be ignored, so that one can create forged sequences accross several instruments. - filename: filename of the uploaded awg file. See :meth:`~make_send_and_load_awg_file` + filename: filename of the uploaded awg file. + See :meth:`~make_send_and_load_awg_file` preservechannelsettings: see :meth:`~make_send_and_load_awg_file` """ @@ -1043,7 +1053,8 @@ def make_awg_file_from_forged_sequence(self, seq, channel_mapping, self.available_marker_channels = [f'{m}M{c}' for c in self.available_signal_channels for m in [1,2]] - self.available_channels = self.available_signal_channels + self.available_marker_channels + self.available_channels = (self.available_signal_channels + + self.available_marker_channels) waveforms = [] m1s = [] From a6a7ec651e6cb5f2d818017a59e7aaabd61efd71 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 26 Jun 2018 15:50:11 +0200 Subject: [PATCH 004/719] more cosmetics --- .../instrument_drivers/tektronix/AWG5014.py | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 4e0c1d2ca05..00e80f68350 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1026,15 +1026,19 @@ def mrkdeltrans(x): def parse_marker_channel_name(name:str)->Tupel[int, int]: """ - returns from the channel index and marker index from a marker descriptor string e.g. '1M1'->(1,1) + returns from the channel index and marker index from a marker + descriptor string e.g. '1M1'->(1,1) """ res = re.match('^(?P\d+)M(?P\d+)$', name) assert res is not None MarkerDescriptor = namedtuple('MarkerDescriptor', 'marker', 'channel') - return MarkerDescriptor(int(res.group('marker')), int(res.group('channel'))) + return MarkerDescriptor(int(res.group('marker')), + int(res.group('channel'))) - def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', preservechannelsettings=True): + def make_awg_file_from_forged_sequence(self, seq, + filename='customawgfile.awg', + preservechannelsettings=True): """ Makes an awg file form a forged sequence as produced by broadbean.sequence.Sequence.forge. The forged sequence is a dictionary @@ -1059,7 +1063,10 @@ def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', waveforms = [] m1s = [] m2s = [] - # unfortunately the definitions of the sequence elements in terms of channel and step in :meth:`make_and_send_awg_file` and the forged sequence definition are transposed. Start by filling out after schema and transpose at the end + # unfortunately the definitions of the sequence elements in terms of + # channel and step in :meth:`make_and_send_awg_file` and the forged + # sequence definition are transposed. Start by filling out after schema + # and transpose at the end. # make...: [[wfm1ch1, wfm2ch1, ...], [wfm1ch2, wfm2ch2], ...] # dict efectively: {elementid: {channelid: wfm}} physical_channels = [] @@ -1075,16 +1082,20 @@ def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', assert elem['type'] == 'element' content = elem['content'] assert len(content.keys()) == 1 - # there is only one element int the dict with key `1` in case of type == element - # and no sequencing information, i.e. there is only one entry with key 'data' + # there is only one element int the dict with key `1` in case of + # type == element and no sequencing information, i.e. there is only + # one entry with key 'data' # waveform data datadict = content[1]['data'] # obtain list of channels defined in the first step if first_step: - mapped_channels = [channel_mapping.get(k, None) for k in datadict.keys()] - # filter out all channels that are not relevant for this instrument - physical_channels = [v for v in mapped_channels if v in self.available_signal_channels] + mapped_channels = [channel_mapping.get(k, None) + for k in datadict.keys()] + # filter out all channels that are not relevant for this + # instrument + physical_channels = [v for v in mapped_channels + if v in self.available_signal_channels] first_step = False # create empty list with size of number of used channels @@ -1099,7 +1110,8 @@ def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', assert res is not None step_marker[int(res.group('marker'))-1][int(res.group('channel'))-1] = data elif physical_channel in self.available_signal_channels: - # treat the first step differently: here the channel order is defined + # treat the first step differently: here the channel order + # is defined try: index = physical_channels.index(physical_channel) except IndexError: @@ -1107,15 +1119,18 @@ def make_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', raise step_waveforms[index] = data else: - # only proceed if the defined channel is available on the instrument - # TODO: this needs some extra information in case we are using two instruments with the same channel names + # only proceed if the defined channel is available on the + # instrument + # TODO: this needs some extra information in case we are + # using two instruments with the same channel names # e.g. always add a prefix with the instrument name. continue if any(x is None for x in step_waveforms): # TODO: error message raise RuntimeError - #TODO: make more general such that one can create a sequence without signals but only markers + #TODO: make more general such that one can create a sequence + # without signals but only markers n_samples = len(step_waveforms[0]) for j in range(n_channels): for i in range(2): From 76c0f3388fe1deb908006ce05f63c19494ca93d2 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 26 Jun 2018 16:39:47 +0200 Subject: [PATCH 005/719] converted to broadbean routing --- .../instrument_drivers/tektronix/AWG5014.py | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 00e80f68350..4700576f719 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -12,6 +12,7 @@ from qcodes import VisaInstrument, validators as vals from pyvisa.errors import VisaIOError +from broadbean.tools import forged_sequence_dict_to_list log = logging.getLogger(__name__) @@ -1076,44 +1077,45 @@ def make_awg_file_from_forged_sequence(self, seq, goto_states = [] jump_tos = [] - first_step = True - for step, elem in seq.items(): + # convert to list + seq = forged_sequence_dict_to_list(seq) + + # obtain list of channels defined in the first step + if len(seq) < 1: + # TODO: better error + raise RuntimeError('Sequences need to have at least one element') + + # mapped_channels = [channel_mapping.get(k, None) + # for k in datadict.keys()] + # # filter out all channels that are not relevant for this + # # instrument + + # treat the first step differently: here the channel order + # is defined + used_channels = list(seq[0]['content'][0]['data'].keys()) + # physical_channels = [v for v in mapped_channels + # if v in self.available_signal_channels] + for elem in seq: # TODO: add support for subsequences assert elem['type'] == 'element' content = elem['content'] - assert len(content.keys()) == 1 + assert len(content) == 1 # there is only one element int the dict with key `1` in case of # type == element and no sequencing information, i.e. there is only # one entry with key 'data' # waveform data - datadict = content[1]['data'] - - # obtain list of channels defined in the first step - if first_step: - mapped_channels = [channel_mapping.get(k, None) - for k in datadict.keys()] - # filter out all channels that are not relevant for this - # instrument - physical_channels = [v for v in mapped_channels - if v in self.available_signal_channels] - first_step = False + datadict = content[0]['data'] # create empty list with size of number of used channels - step_waveforms = [None] * len(physical_channels) + step_waveforms = [None] * len(used_channels) step_marker = [[None] * n_channels] * 2 - for channel_id, data in datadict.items(): - physical_channel = channel_mapping.get(channel_id, None) - - if physical_channel in self.available_marker_channels: - res = re.match('^(?P\d+)M(?P\d+)$', - physical_channel) - assert res is not None - step_marker[int(res.group('marker'))-1][int(res.group('channel'))-1] = data - elif physical_channel in self.available_signal_channels: - # treat the first step differently: here the channel order - # is defined + for channel, data in datadict.items(): + if channel in self.available_marker_channels: + t = self.parse_marker_channel_name(channel) + step_marker[t.marker-1][t.channel-1] = data + elif channel in self.available_signal_channels: try: - index = physical_channels.index(physical_channel) + index = used_channels.index(channel) except IndexError: #TODO: write error message raise From 4b605697f9022c24ea790a9f16df06c2c10892ab Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 27 Jun 2018 10:47:04 +0200 Subject: [PATCH 006/719] debugging driver --- .../instrument_drivers/tektronix/AWG5014.py | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 4700576f719..28756abc66b 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -2,6 +2,9 @@ import logging import warnings import re +from collections import namedtuple + +from typing import Tuple import numpy as np import array as arr @@ -1024,8 +1027,8 @@ def mrkdeltrans(x): return AWG_channel_cfg - - def parse_marker_channel_name(name:str)->Tupel[int, int]: + @staticmethod + def parse_marker_channel_name(name:str)->Tuple[int, int]: """ returns from the channel index and marker index from a marker descriptor string e.g. '1M1'->(1,1) @@ -1033,7 +1036,8 @@ def parse_marker_channel_name(name:str)->Tupel[int, int]: res = re.match('^(?P\d+)M(?P\d+)$', name) assert res is not None - MarkerDescriptor = namedtuple('MarkerDescriptor', 'marker', 'channel') + MarkerDescriptor = namedtuple('MarkerDescriptor', + ('marker', 'channel')) return MarkerDescriptor(int(res.group('marker')), int(res.group('channel'))) @@ -1070,7 +1074,6 @@ def make_awg_file_from_forged_sequence(self, seq, # and transpose at the end. # make...: [[wfm1ch1, wfm2ch1, ...], [wfm1ch2, wfm2ch2], ...] # dict efectively: {elementid: {channelid: wfm}} - physical_channels = [] nreps = [] trig_waits = [] @@ -1084,17 +1087,13 @@ def make_awg_file_from_forged_sequence(self, seq, if len(seq) < 1: # TODO: better error raise RuntimeError('Sequences need to have at least one element') - - # mapped_channels = [channel_mapping.get(k, None) - # for k in datadict.keys()] - # # filter out all channels that are not relevant for this - # # instrument # treat the first step differently: here the channel order # is defined - used_channels = list(seq[0]['content'][0]['data'].keys()) - # physical_channels = [v for v in mapped_channels - # if v in self.available_signal_channels] + # TODO: this could made such that it fails if not all channels are + # accounted for. Now it will fail in the next step. + used_channels = [k for k in seq[0]['content'][0]['data'].keys() + if k in self.available_signal_channels] for elem in seq: # TODO: add support for subsequences assert elem['type'] == 'element' @@ -1155,7 +1154,7 @@ def make_awg_file_from_forged_sequence(self, seq, self.make_send_and_load_awg_file(waveforms, m1s, m2s, nreps, trig_waits, goto_states, jump_tos, - channels=physical_channels, + channels=used_channels, filename=filename, preservechannelsettings=preservechannelsettings) def generate_awg_file(self, From 5e2844b3687802efab8e8b32754e07108e02f6cc Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 28 Jun 2018 16:42:52 +0200 Subject: [PATCH 007/719] fixing marker transpose --- qcodes/instrument_drivers/tektronix/AWG5014.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 28756abc66b..652ea165c46 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1148,6 +1148,8 @@ def make_awg_file_from_forged_sequence(self, seq, jump_tos.append(seq_opts.get('jump_to', 0)) # transpose list of lists waveforms = [list(x) for x in zip(*waveforms)] + m1s = [list(x) for x in zip(*m1s)] + m2s = [list(x) for x in zip(*m2s)] channel_cfg = {} From 96d18a1e0d39beedd908b0d066422ed72190920b Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Fri, 29 Jun 2018 14:00:36 +0200 Subject: [PATCH 008/719] gave method the right name --- qcodes/instrument_drivers/tektronix/AWG5014.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index f7a5a971302..d3ca4275d28 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1042,7 +1042,7 @@ def parse_marker_channel_name(name:str)->Tuple[int, int]: return MarkerDescriptor(int(res.group('marker')), int(res.group('channel'))) - def make_awg_file_from_forged_sequence(self, seq, + def make_send_and_load_awg_file_from_forged_sequence(self, seq, filename='customawgfile.awg', preservechannelsettings=True): """ From 46cade6129de0fd1f9af378181a31929832d8420 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 10 Jul 2018 10:51:41 +0200 Subject: [PATCH 009/719] adaption to lists --- qcodes/instrument_drivers/tektronix/AWG5014.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index d3ca4275d28..95c0c2493c7 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -18,7 +18,7 @@ from qcodes.utils.deprecate import deprecate from pyvisa.errors import VisaIOError -from broadbean.tools import forged_sequence_dict_to_list +from broadbean.tools import forged_sequence_dict_to_list, is_subsequence log = logging.getLogger(__name__) @@ -1081,9 +1081,6 @@ def make_send_and_load_awg_file_from_forged_sequence(self, seq, goto_states = [] jump_tos = [] - # convert to list - seq = forged_sequence_dict_to_list(seq) - # obtain list of channels defined in the first step if len(seq) < 1: # TODO: better error @@ -1093,18 +1090,12 @@ def make_send_and_load_awg_file_from_forged_sequence(self, seq, # is defined # TODO: this could made such that it fails if not all channels are # accounted for. Now it will fail in the next step. - used_channels = [k for k in seq[0]['content'][0]['data'].keys() + used_channels = [k for k in seq[0]['data'].keys() if k in self.available_signal_channels] for elem in seq: # TODO: add support for subsequences - assert elem['type'] == 'element' - content = elem['content'] - assert len(content) == 1 - # there is only one element int the dict with key `1` in case of - # type == element and no sequencing information, i.e. there is only - # one entry with key 'data' - # waveform data - datadict = content[0]['data'] + assert not is_subsequence(elem) + datadict = elem['data'] # create empty list with size of number of used channels step_waveforms = [None] * len(used_channels) From 0217c445c85a13ea512f31b854696d90d9f4a68c Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Fri, 13 Jul 2018 17:53:26 +0200 Subject: [PATCH 010/719] fix double marker from * operator trap --- qcodes/instrument_drivers/tektronix/AWG5014.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 95c0c2493c7..3951a6d232c 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1099,7 +1099,7 @@ def make_send_and_load_awg_file_from_forged_sequence(self, seq, # create empty list with size of number of used channels step_waveforms = [None] * len(used_channels) - step_marker = [[None] * n_channels] * 2 + step_marker = [[None] * n_channels, [None] * n_channels] for channel, data in datadict.items(): if channel in self.available_marker_channels: t = self.parse_marker_channel_name(channel) From 9f5e9442299213bb67288dd282bbfbbb5a8c3a72 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 19 Jul 2018 14:05:11 +0200 Subject: [PATCH 011/719] add markers on empty channels --- .../instrument_drivers/tektronix/AWG5014.py | 146 ++++++++++-------- 1 file changed, 84 insertions(+), 62 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 3951a6d232c..87a19bc8bac 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -3,6 +3,7 @@ import warnings import re from collections import namedtuple +from collections import defaultdict from typing import Tuple @@ -18,7 +19,9 @@ from qcodes.utils.deprecate import deprecate from pyvisa.errors import VisaIOError -from broadbean.tools import forged_sequence_dict_to_list, is_subsequence +from broadbean.tools import (forged_sequence_dict_to_list, + is_subsequence, get_element_channel_ids) + log = logging.getLogger(__name__) @@ -909,7 +912,7 @@ def generate_channel_cfg(self): been changed from their default value and put them in a dictionary that can easily be written into an awg file, so as to prevent said awg file from falling back to default values. - (See :meth:`~make_awg_file` and :meth:`qcodes.instrument_drivers.tektronix.AWG5014.Tektronix_AWG5014.AWG_FILE_FORMAT_CHANNEL`) + (See :meth:`~make_awg_file` and :meth:`~AWG_FILE_FORMAT_CHANNEL`) NOTE: This only works for settings changed via the corresponding QCoDeS parameter. @@ -1028,23 +1031,24 @@ def mrkdeltrans(x): return AWG_channel_cfg - @staticmethod - def parse_marker_channel_name(name:str)->Tuple[int, int]: + @staticmethod + def parse_marker_channel_name(name: str)->Tuple[int, int]: """ returns from the channel index and marker index from a marker descriptor string e.g. '1M1'->(1,1) """ - res = re.match('^(?P\d+)M(?P\d+)$', - name) + res = re.match(r'^(?P\d+)M(?P\d+)$', + name) assert res is not None MarkerDescriptor = namedtuple('MarkerDescriptor', ('marker', 'channel')) return MarkerDescriptor(int(res.group('marker')), int(res.group('channel'))) - def make_send_and_load_awg_file_from_forged_sequence(self, seq, - filename='customawgfile.awg', - preservechannelsettings=True): + def make_send_and_load_awg_file_from_forged_sequence( + self, seq, + filename='customawgfile.awg', + preservechannelsettings=True): """ Makes an awg file form a forged sequence as produced by broadbean.sequence.Sequence.forge. The forged sequence is a dictionary @@ -1059,11 +1063,12 @@ def make_send_and_load_awg_file_from_forged_sequence(self, seq, """ n_channels = 4 - self.available_signal_channels = list(range(1,n_channels+1)) - self.available_marker_channels = [f'{m}M{c}' - for c in self.available_signal_channels - for m in [1,2]] - self.available_channels = (self.available_signal_channels + + self.available_waveform_channels = list(range(1, n_channels+1)) + self.available_marker_channels = [ + f'{c}M{m}' + for c in self.available_waveform_channels + for m in [1, 2]] + self.available_channels = (self.available_waveform_channels + self.available_marker_channels) waveforms = [] @@ -1085,72 +1090,87 @@ def make_send_and_load_awg_file_from_forged_sequence(self, seq, if len(seq) < 1: # TODO: better error raise RuntimeError('Sequences need to have at least one element') - - # treat the first step differently: here the channel order - # is defined - # TODO: this could made such that it fails if not all channels are - # accounted for. Now it will fail in the next step. - used_channels = [k for k in seq[0]['data'].keys() - if k in self.available_signal_channels] - for elem in seq: + + # assume that the channels are the same on every element + provided_channels = get_element_channel_ids(seq[0]) + used_waveform_channels = list(set(provided_channels).intersection( + set(self.available_waveform_channels))) + used_marker_channels = list(set(provided_channels).intersection( + set(self.available_marker_channels))) + associated_marker_channels = [ + self.parse_marker_channel_name(name).channel + for name in used_marker_channels] + used_channels = list( + set(used_waveform_channels).union(set(associated_marker_channels))) + + for i_elem, elem in enumerate(seq): # TODO: add support for subsequences assert not is_subsequence(elem) datadict = elem['data'] - # create empty list with size of number of used channels - step_waveforms = [None] * len(used_channels) - step_marker = [[None] * n_channels, [None] * n_channels] + # Split up the dictionary into two, one for the markers the other + # for the waveforms + step_waveforms = {} + step_markers = defaultdict(None), defaultdict(None) for channel, data in datadict.items(): if channel in self.available_marker_channels: t = self.parse_marker_channel_name(channel) - step_marker[t.marker-1][t.channel-1] = data - elif channel in self.available_signal_channels: - try: - index = used_channels.index(channel) - except IndexError: - #TODO: write error message - raise - step_waveforms[index] = data + step_markers[t.marker-1][t.channel] = data + elif channel in self.available_waveform_channels: + step_waveforms[channel] = data else: - # only proceed if the defined channel is available on the - # instrument - # TODO: this needs some extra information in case we are - # using two instruments with the same channel names - # e.g. always add a prefix with the instrument name. - continue - - if any(x is None for x in step_waveforms): - # TODO: error message - raise RuntimeError - #TODO: make more general such that one can create a sequence - # without signals but only markers - n_samples = len(step_waveforms[0]) - for j in range(n_channels): + raise RuntimeError( + f'The channel with name {channel} as defined in ' + f'the element with no. {i_elem} is not an available ' + f'marker channel or waveform channel.\n' + f'Available channels are: ' + f'{self.available_marker_channels} and ' + f'{self.available_waveform_channels}') + + # create empty trace as template for filling traces with markers + # only and traces without markers + n_samples = None + waveform_keys = list(step_waveforms.keys()) + marker_keys = tuple(list(step_markers[i].keys()) for i in range(2)) + if len(waveform_keys) != 0: + n_samples = len(step_waveforms[waveform_keys[0]]) + else: for i in range(2): - if step_marker[i][j] is None: - step_marker[i][j] = np.zeros(n_samples) - waveforms.append(step_waveforms) - m1s.append(step_marker[0]) - m2s.append(step_marker[1]) + if len(marker_keys[i]) != 0: + n_samples = len(step_markers[marker_keys[i][0]]) + break + if n_samples is None: + raise RuntimeError('It is not allowed to upload an element ' + 'without markers nor waveforms') + blank_trace = np.zeros(n_samples) + # I think this does might add some traces dynamically if they are + # not the same in all elements. Add check in the beginning + step_waveforms_list = [step_waveforms.get(key, blank_trace) + for key in used_channels] + step_markers_list = tuple([step_markers[i].get(key, blank_trace) + for key in used_channels] + for i in range(2)) + + waveforms.append(step_waveforms_list) + m1s.append(step_markers_list[0]) + m2s.append(step_markers_list[1]) # sequencing seq_opts = elem['sequencing'] nreps.append(seq_opts.get('nrep', 1)) trig_waits.append(seq_opts.get('trig_wait', 0)) - goto_states.append(seq_opts.get('goto_state',0)) + goto_states.append(seq_opts.get('goto_state', 0)) jump_tos.append(seq_opts.get('jump_to', 0)) # transpose list of lists waveforms = [list(x) for x in zip(*waveforms)] m1s = [list(x) for x in zip(*m1s)] m2s = [list(x) for x in zip(*m2s)] - channel_cfg = {} - self.make_send_and_load_awg_file(waveforms, m1s, m2s, - nreps, trig_waits, - goto_states, jump_tos, - channels=used_channels, - filename=filename, - preservechannelsettings=preservechannelsettings) + nreps, trig_waits, + goto_states, jump_tos, + channels=used_channels, + filename=filename, + preservechannelsettings=preservechannelsettings) def _generate_awg_file(self, packed_waveforms, wfname_l, nrep, trig_wait, @@ -1294,7 +1314,8 @@ def _generate_awg_file(self, return awg_file @deprecate(alternative='make_awg_file, _generate_awg_file') - @wraps(_generate_awg_file, assigned=tuple(v for v in WRAPPER_ASSIGNMENTS if v != '__name__')) + @wraps(_generate_awg_file, assigned=tuple(v for v in WRAPPER_ASSIGNMENTS + if v != '__name__')) def generate_awg_file(self, *args, **kwargs): return self._generate_awg_file(*args, **kwargs) @@ -1611,7 +1632,8 @@ def _pack_waveform(self, wf, m1, m2): return packed_wf @deprecate(reason='this function is for private use only.') - @wraps(_pack_waveform, assigned=tuple(v for v in WRAPPER_ASSIGNMENTS if v != '__name__')) + @wraps(_pack_waveform, assigned=tuple(v for v in WRAPPER_ASSIGNMENTS + if v != '__name__')) def pack_waveform(self, *args, **kwargs): return self._pack_waveform(*args, **kwargs) From 1e1f993eb488360cfee478f5766bf7f8af1be67c Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 19 Jul 2018 14:21:31 +0200 Subject: [PATCH 012/719] Remove unused import --- qcodes/instrument_drivers/tektronix/AWG5014.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 87a19bc8bac..d0bfd21c9d5 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -19,8 +19,7 @@ from qcodes.utils.deprecate import deprecate from pyvisa.errors import VisaIOError -from broadbean.tools import (forged_sequence_dict_to_list, - is_subsequence, get_element_channel_ids) +from broadbean.tools import is_subsequence, get_element_channel_ids log = logging.getLogger(__name__) From b97618bcb1479cffc33e9b3b195158eb19f44cc3 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Thu, 4 Oct 2018 15:02:33 +0200 Subject: [PATCH 013/719] [WIP] Azure pipelines add coverage This is WIP until we figure out how to set the right permissions --- azure-pipelines.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eedac3a5252..21b0598d221 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -40,3 +40,8 @@ jobs: inputs: testResultsFiles: 'qcodes\test-*.xml' testRunTitle: 'Publish test results' + - task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: '$(System.DefaultWorkingDirectory)\qcodes\coverage.xml' + reportDirectory: '$(System.DefaultWorkingDirectory)\qcodes\htmlcov' From 9de0f377934f77b8438e0c077d984aba2b5287b2 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 12 Oct 2018 17:20:29 +0200 Subject: [PATCH 014/719] Try to publish docs as a build artifact --- azure-pipelines.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a3b3a4119d1..09565394bbf 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -37,11 +37,16 @@ jobs: cd qcodes pytest --junitxml=test-results.xml --cov=qcodes --cov-report=xml --cov-report=html --cov-config=.coveragerc displayName: "Pytest" + - task: PublishTestResults@1 + inputs: + testResultsFiles: 'qcodes\test-*.xml' + testRunTitle: 'Publish test results' - script: | cd docs make.bat htmlapi displayName: "docsbuild" - - task: PublishTestResults@1 + - task: PublishBuildArtifacts@1 inputs: - testResultsFiles: 'qcodes\test-*.xml' - testRunTitle: 'Publish test results' + pathtoPublish: 'docs/_build/html' + artifactName: 'docs' + publishLocation: 'Container' From c6a89b93cf10487be9015768fccc2fce6ebe6a3a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 15 Oct 2018 15:19:37 +0200 Subject: [PATCH 015/719] Add types to ctypes dll calls These matches the calling conventions from the headers --- .../signal_hound/USB_SA124B.py | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 01f24221d51..286a4f003e7 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -178,6 +178,40 @@ def __init__(self, name, dll_path=None, **kwargs): self._trace_updated = False log.info('Initializing instrument SignalHound USB 124B') self.dll = ct.CDLL(dll_path or self.dll_path) + + self.dll.saConfigCenterSpan.argtypes = [ct.c_int, + ct.c_double, + ct.c_double] + self.dll.saConfigAcquisition.argtypes = [ct.c_int, + ct.c_int, + ct.c_int] + self.dll.saConfigLevel.argtypes = [ct.c_int, + ct.c_double] + self.dll.saSetTimebase.argtypes = [ct.c_int, + ct.c_int] + self.dll.saConfigSweepCoupling.argypes = [ct.c_int, + ct.c_double, + ct.c_double, + ct.c_bool] + self.dll.saInitiate.argtypes = [ct.c_int, + ct.c_int, + ct.c_int] + self.dll.saOpenDevice.argtypes = [ct.POINTER(ct.c_int)] + self.dll.saCloseDevice.argtypes = [ct.c_int] + self.dll.saPreset.argtypes = [ct.c_int] + self.dll.saGetDeviceType.argtypes = [ct.c_int, + ct.POINTER(ct.c_int)] + self.dll.saQuerySweepInfo.argtypes = [ct.c_int, + ct.POINTER(ct.c_int), + ct.POINTER(ct.c_double), + ct.POINTER(ct.c_double)] + self.dll.saGetSweep_32f.argtypes = [ct.c_int, ct.POINTER(ct.c_float), + ct.POINTER(ct.c_float)] + self.dll.saGetSerialNumber.argtypes = [ct.c_int, + ct.POINTER(ct.c_int)] + self.dll.saGetFirmwareString.argtypes = [ct.c_int, + ct.c_char_p] + self.hf = Constants self.add_parameter('frequency', label='Frequency', @@ -361,14 +395,14 @@ def sync_parameters(self) -> None: # 2. Acquisition configuration detectorVals = { - 'min-max': ct.c_uint(self.hf.sa_MIN_MAX), - 'average': ct.c_uint(self.hf.sa_AVERAGE) + 'min-max': ct.c_int(self.hf.sa_MIN_MAX), + 'average': ct.c_int(self.hf.sa_AVERAGE) } scaleVals = { - 'log-scale': ct.c_uint(self.hf.sa_LOG_SCALE), - 'lin-scale': ct.c_uint(self.hf.sa_LIN_SCALE), - 'log-full-scale': ct.c_uint(self.hf.sa_LOG_FULL_SCALE), - 'lin-full-scale': ct.c_uint(self.hf.sa_LIN_FULL_SCALE) + 'log-scale': ct.c_int(self.hf.sa_LOG_SCALE), + 'lin-scale': ct.c_int(self.hf.sa_LIN_SCALE), + 'log-full-scale': ct.c_int(self.hf.sa_LOG_FULL_SCALE), + 'lin-full-scale': ct.c_int(self.hf.sa_LIN_FULL_SCALE) } detector = detectorVals[self.acquisition_mode()] scale = scaleVals[self.scale()] @@ -502,7 +536,7 @@ def _get_device_type(self) -> str: """ log.info('Querying device for model information') - devType = ct.c_uint(0) + devType = ct.c_int(0) devTypePnt = ct.pointer(devType) err = self.dll.saGetDeviceType(self.deviceHandle, devTypePnt) @@ -605,7 +639,7 @@ def _get_power_at_freq(self) -> float: self.rbw(1e3) if not self._parameters_synced: # call configure to update both - # the paramters on the device and the + # the parameters on the device and the # setpoints and units self.configure() data = self._get_averaged_sweep_data() From d2a6358201b5a4d4fbc119b693c7b5e908b6a03b Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 15 Oct 2018 15:20:31 +0200 Subject: [PATCH 016/719] Simplify get data logic Recursively call the code rather than duplication and store directly into numpy arrays --- .../signal_hound/USB_SA124B.py | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 286a4f003e7..ffb6be2b2c0 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -578,11 +578,15 @@ def QuerySweep(self) -> Tuple[int, float, float]: return sweep_len.value, start_freq.value, stepsize.value - def _get_sweep_data(self) -> np.ndarray: + def _get_sweep_data(self, retry: bool=False) -> np.ndarray: """ This function performs a sweep over the configured ranges. The result of the sweep is returned along with the sweep points + Args: + retry: It this the second attempt? This method will attempt + to get the data exactly twice. + returns: datamin numpy array """ @@ -590,25 +594,20 @@ def _get_sweep_data(self) -> np.ndarray: self.sync_parameters() sweep_len, _, _ = self.QuerySweep() - minarr = (ct.c_float * sweep_len)() - maxarr = (ct.c_float * sweep_len)() - sleep_time = self.sleep_time.get() - sleep(sleep_time) # Added extra sleep for updating issue + datamin = np.zeros((sweep_len), dtype=np.float32) + datamax = np.zeros((sweep_len), dtype=np.float32) + + minarr = datamin.ctypes.data_as(ct.POINTER(ct.c_float)) + maxarr = datamax.ctypes.data_as(ct.POINTER(ct.c_float)) + + sleep(self.sleep_time.get()) # Added extra sleep for updating issue err = self.dll.saGetSweep_32f(self.deviceHandle, minarr, maxarr) - sleep(sleep_time) # Added extra sleep - if not err == saStatus.saNoError: - # if an error occurs tries preparing the device and then asks again + if not err == saStatus.saNoError and not retry: log.warning('Error raised in _get_sweep_data, ' - 'trying to get data') - sleep(sleep_time) - self.sync_parameters() - sleep(sleep_time) - minarr = (ct.c_float * sweep_len)() - maxarr = (ct.c_float * sweep_len)() - err = self.dll.saGetSweep_32f(self.deviceHandle, minarr, maxarr) - self.check_for_error(err, 'saGetSweep_32f') - - datamin = np.array([minarr[elem] for elem in range(sweep_len)]) + 'retrying to get data') + datamin = self._get_sweep_data(retry=True) + else: + self.check_for_error(err, 'saGetSweep_32f') return datamin From 74013a4f239be2e0dd26265461278c507012caea Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 15 Oct 2018 15:40:14 +0200 Subject: [PATCH 017/719] Simplify avg logic --- .../signal_hound/USB_SA124B.py | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index ffb6be2b2c0..76f54f59d1a 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -578,7 +578,7 @@ def QuerySweep(self) -> Tuple[int, float, float]: return sweep_len.value, start_freq.value, stepsize.value - def _get_sweep_data(self, retry: bool=False) -> np.ndarray: + def _get_sweep_data(self) -> np.ndarray: """ This function performs a sweep over the configured ranges. The result of the sweep is returned along with the sweep points @@ -594,34 +594,31 @@ def _get_sweep_data(self, retry: bool=False) -> np.ndarray: self.sync_parameters() sweep_len, _, _ = self.QuerySweep() - datamin = np.zeros((sweep_len), dtype=np.float32) - datamax = np.zeros((sweep_len), dtype=np.float32) - minarr = datamin.ctypes.data_as(ct.POINTER(ct.c_float)) - maxarr = datamax.ctypes.data_as(ct.POINTER(ct.c_float)) + data = np.zeros(sweep_len) + Navg = self.avg() + for i in range(Navg): - sleep(self.sleep_time.get()) # Added extra sleep for updating issue - err = self.dll.saGetSweep_32f(self.deviceHandle, minarr, maxarr) - if not err == saStatus.saNoError and not retry: - log.warning('Error raised in _get_sweep_data, ' - 'retrying to get data') - datamin = self._get_sweep_data(retry=True) - else: + datamin = np.zeros((sweep_len), dtype=np.float32) + datamax = np.zeros((sweep_len), dtype=np.float32) + + minarr = datamin.ctypes.data_as(ct.POINTER(ct.c_float)) + maxarr = datamax.ctypes.data_as(ct.POINTER(ct.c_float)) + + sleep(self.sleep_time.get()) # Added extra sleep for updating issue + err = self.dll.saGetSweep_32f(self.deviceHandle, minarr, maxarr) self.check_for_error(err, 'saGetSweep_32f') + data += datamin - return datamin + return data / Navg def _get_averaged_sweep_data(self) -> np.ndarray: """ Averages over SH.sweep Navg times """ - sweep_len, _, _ = self.QuerySweep() - data = np.zeros(sweep_len) - Navg = self.avg() - for i in range(Navg): - data += self._get_sweep_data() - return data / Navg + data = self._get_sweep_data() + return data def _get_power_at_freq(self) -> float: """ From 884abe0ef1ff3a6dffab81d13cc8345023b2c1dc Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 15 Oct 2018 16:11:47 +0200 Subject: [PATCH 018/719] remove avg_data method that serves no use now --- qcodes/instrument_drivers/signal_hound/USB_SA124B.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 76f54f59d1a..6d8e657fa06 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -145,7 +145,7 @@ def get_raw(self) -> np.ndarray: "for 'SignalHound_USB_SA124B'") if not self.instrument._trace_updated: raise RuntimeError('trace not updated, run configure to update') - data = self._instrument._get_averaged_sweep_data() + data = self._instrument._get_sweep_data() sleep(2*self.instrument.sleep_time.get()) return data @@ -612,14 +612,6 @@ def _get_sweep_data(self) -> np.ndarray: return data / Navg - def _get_averaged_sweep_data(self) -> np.ndarray: - """ - Averages over SH.sweep Navg times - - """ - data = self._get_sweep_data() - return data - def _get_power_at_freq(self) -> float: """ Returns the maximum power in a window of 250 kHz @@ -638,7 +630,7 @@ def _get_power_at_freq(self) -> float: # the parameters on the device and the # setpoints and units self.configure() - data = self._get_averaged_sweep_data() + data = self._get_sweep_data() max_power = np.max(data) if needs_reset: self.span(original_span) From 5572ef22409eda2e935ac3de5f9fe07c87721039 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 16 Oct 2018 09:21:44 +0200 Subject: [PATCH 019/719] remove out of date arg --- qcodes/instrument_drivers/signal_hound/USB_SA124B.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 6d8e657fa06..1ecf14f56ff 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -583,10 +583,6 @@ def _get_sweep_data(self) -> np.ndarray: This function performs a sweep over the configured ranges. The result of the sweep is returned along with the sweep points - Args: - retry: It this the second attempt? This method will attempt - to get the data exactly twice. - returns: datamin numpy array """ From 495b8732293b63ed991ac70e93f18c147502f005 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 16 Oct 2018 09:25:27 +0200 Subject: [PATCH 020/719] refactor ctypes argtypes into their own method --- .../signal_hound/USB_SA124B.py | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 1ecf14f56ff..a8cda68a834 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -179,38 +179,7 @@ def __init__(self, name, dll_path=None, **kwargs): log.info('Initializing instrument SignalHound USB 124B') self.dll = ct.CDLL(dll_path or self.dll_path) - self.dll.saConfigCenterSpan.argtypes = [ct.c_int, - ct.c_double, - ct.c_double] - self.dll.saConfigAcquisition.argtypes = [ct.c_int, - ct.c_int, - ct.c_int] - self.dll.saConfigLevel.argtypes = [ct.c_int, - ct.c_double] - self.dll.saSetTimebase.argtypes = [ct.c_int, - ct.c_int] - self.dll.saConfigSweepCoupling.argypes = [ct.c_int, - ct.c_double, - ct.c_double, - ct.c_bool] - self.dll.saInitiate.argtypes = [ct.c_int, - ct.c_int, - ct.c_int] - self.dll.saOpenDevice.argtypes = [ct.POINTER(ct.c_int)] - self.dll.saCloseDevice.argtypes = [ct.c_int] - self.dll.saPreset.argtypes = [ct.c_int] - self.dll.saGetDeviceType.argtypes = [ct.c_int, - ct.POINTER(ct.c_int)] - self.dll.saQuerySweepInfo.argtypes = [ct.c_int, - ct.POINTER(ct.c_int), - ct.POINTER(ct.c_double), - ct.POINTER(ct.c_double)] - self.dll.saGetSweep_32f.argtypes = [ct.c_int, ct.POINTER(ct.c_float), - ct.POINTER(ct.c_float)] - self.dll.saGetSerialNumber.argtypes = [ct.c_int, - ct.POINTER(ct.c_int)] - self.dll.saGetFirmwareString.argtypes = [ct.c_int, - ct.c_char_p] + self._set_ctypes_argtypes() self.hf = Constants self.add_parameter('frequency', @@ -356,6 +325,45 @@ def __init__(self, name, dll_path=None, **kwargs): self.connect_message() + def _set_ctypes_argtypes(self) -> None: + """ + Set the expected argtypes for function calls in the sa_api dll + These should match the function signatures defined in the sa-api + header files included with the signal hound sdk + """ + self.dll.saConfigCenterSpan.argtypes = [ct.c_int, + ct.c_double, + ct.c_double] + self.dll.saConfigAcquisition.argtypes = [ct.c_int, + ct.c_int, + ct.c_int] + self.dll.saConfigLevel.argtypes = [ct.c_int, + ct.c_double] + self.dll.saSetTimebase.argtypes = [ct.c_int, + ct.c_int] + self.dll.saConfigSweepCoupling.argypes = [ct.c_int, + ct.c_double, + ct.c_double, + ct.c_bool] + self.dll.saInitiate.argtypes = [ct.c_int, + ct.c_int, + ct.c_int] + self.dll.saOpenDevice.argtypes = [ct.POINTER(ct.c_int)] + self.dll.saCloseDevice.argtypes = [ct.c_int] + self.dll.saPreset.argtypes = [ct.c_int] + self.dll.saGetDeviceType.argtypes = [ct.c_int, + ct.POINTER(ct.c_int)] + self.dll.saQuerySweepInfo.argtypes = [ct.c_int, + ct.POINTER(ct.c_int), + ct.POINTER(ct.c_double), + ct.POINTER(ct.c_double)] + self.dll.saGetSweep_32f.argtypes = [ct.c_int, ct.POINTER(ct.c_float), + ct.POINTER(ct.c_float)] + self.dll.saGetSerialNumber.argtypes = [ct.c_int, + ct.POINTER(ct.c_int)] + self.dll.saGetFirmwareString.argtypes = [ct.c_int, + ct.c_char_p] + def _update_trace(self) -> None: """ Private method to sync changes of the @@ -536,7 +544,7 @@ def _get_device_type(self) -> str: """ log.info('Querying device for model information') - devType = ct.c_int(0) + devType = ct.c_int32(0) devTypePnt = ct.pointer(devType) err = self.dll.saGetDeviceType(self.deviceHandle, devTypePnt) From da1b072485b5a338f468184c45ac2b203bab269b Mon Sep 17 00:00:00 2001 From: "Esteban A. Martinez" Date: Fri, 19 Oct 2018 15:24:51 +0200 Subject: [PATCH 021/719] Added driver for Basel current preamplifier. --- qcodes/instrument_drivers/basel/__init__.py | 0 qcodes/instrument_drivers/basel/sp983c.py | 35 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 qcodes/instrument_drivers/basel/__init__.py create mode 100644 qcodes/instrument_drivers/basel/sp983c.py diff --git a/qcodes/instrument_drivers/basel/__init__.py b/qcodes/instrument_drivers/basel/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/qcodes/instrument_drivers/basel/sp983c.py b/qcodes/instrument_drivers/basel/sp983c.py new file mode 100644 index 00000000000..a603e2453d0 --- /dev/null +++ b/qcodes/instrument_drivers/basel/sp983c.py @@ -0,0 +1,35 @@ +from qcodes.instrument.base import Instrument +from qcodes.instrument.parameter import MultiParameter +from qcodes.utils.validators import Enum, Bool + + +class SP983C(Instrument): + """ + A virtual driver for the Basel SP 983 current preamplifier. + """ + + def __init__(self, name, **kwargs): + super().__init__(name, **kwargs) + + self.add_parameter('gain', + initial_value=1e8, + label='Gain', + unit='V/A', + get_cmd=None, set_cmd=None, + vals=Enum(1e09, 1e08, 1e07, 1e06, 1e05)) + + self.add_parameter('fcut', + initial_value=1e3, + label='Cutoff frequency', + unit='Hz', + get_cmd=None, set_cmd=None, + vals=Enum(30., 100., 300., 1e3, 3e3, 10e3, 30e3, + 100e3, 1e6)) + + def get_idn(self): + vendor = 'Physics Basel' + model = 'SP 983c' + serial = None + firmware = None + return {'vendor': vendor, 'model': model, + 'serial': serial, 'firmware': firmware} From 25d6150177cbcf38887e2d073ee8d56832b49647 Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Tue, 23 Oct 2018 16:43:01 +0200 Subject: [PATCH 022/719] added the snap XY command to read X and Y together The snap command records the values of X and Y at a single instant. This is a way to query values at the same time. This is important when the time constant is very short, < 100 ms. -> tuple (x,y) --- qcodes/instrument_drivers/stanford_research/SR830.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index f2b4acb5f10..165e725ba79 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -386,7 +386,17 @@ def parse_offset_get(s): get_cmd='OUTP? 4', get_parser=float, unit='deg') - + + self.add_parameter('SNAP_XY', + label='Coherent snapshot of X and Y', + docstring=("The snap command records the values of X and Y at a single instant." + " This is a way to query values at the same time." + " This is important when the time constant is very short, < 100 ms. " + " -> tuple (x,y) " ) + get_cmd='SNAP? 1,2', + get_parser=lambda s: tuple((float(el) for el in s.split(','))), + unit=('V','V')) + # Data buffer settings self.add_parameter('buffer_SR', label='Buffer sample rate', From c69bb9368831e2ba9062857e02f189c137266062 Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Tue, 23 Oct 2018 18:34:10 +0200 Subject: [PATCH 023/719] Update SR830.py typographical error. --- qcodes/instrument_drivers/stanford_research/SR830.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 165e725ba79..9f5e7ea69ae 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -392,7 +392,7 @@ def parse_offset_get(s): docstring=("The snap command records the values of X and Y at a single instant." " This is a way to query values at the same time." " This is important when the time constant is very short, < 100 ms. " - " -> tuple (x,y) " ) + " -> tuple (x,y) " ), get_cmd='SNAP? 1,2', get_parser=lambda s: tuple((float(el) for el in s.split(','))), unit=('V','V')) From f48618ddf08d2d758d7903e7777247871d75117c Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Tue, 23 Oct 2018 18:40:10 +0200 Subject: [PATCH 024/719] changed the parameter to a function ... the snap_xy is now a function using "add_function". in turn get_cmd -> call_cmd, and get_parser -> return_parser. SNAP_XY is also now lowercase --- qcodes/instrument_drivers/stanford_research/SR830.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 9f5e7ea69ae..72389375102 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -387,14 +387,14 @@ def parse_offset_get(s): get_parser=float, unit='deg') - self.add_parameter('SNAP_XY', + self.add_function('snap_xy', label='Coherent snapshot of X and Y', docstring=("The snap command records the values of X and Y at a single instant." " This is a way to query values at the same time." " This is important when the time constant is very short, < 100 ms. " " -> tuple (x,y) " ), - get_cmd='SNAP? 1,2', - get_parser=lambda s: tuple((float(el) for el in s.split(','))), + call_cmd='SNAP? 1,2', + return_parser=lambda s: tuple((float(el) for el in s.split(','))), unit=('V','V')) # Data buffer settings From 6ac42204ff04a29ca1efcacf0aad2998d2c6d3d5 Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Wed, 24 Oct 2018 11:13:35 +0200 Subject: [PATCH 025/719] snap is a flexable class bound method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit snap is now a class bound method. it can be used as lockin.snap('x','y') -> tuple(x,y) it checks for a correct number of parameters and that the parameters are valid. It is not fussy about 'x' or 'X', and the confusing phase option can be 'p', 'P', 'Phase', 'phase', or 'θ'. to help with compatibility between similar drivers. --- .../stanford_research/SR830.py | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 72389375102..68d9d45f4ac 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -387,16 +387,6 @@ def parse_offset_get(s): get_parser=float, unit='deg') - self.add_function('snap_xy', - label='Coherent snapshot of X and Y', - docstring=("The snap command records the values of X and Y at a single instant." - " This is a way to query values at the same time." - " This is important when the time constant is very short, < 100 ms. " - " -> tuple (x,y) " ), - call_cmd='SNAP? 1,2', - return_parser=lambda s: tuple((float(el) for el in s.split(','))), - unit=('V','V')) - # Data buffer settings self.add_parameter('buffer_SR', label='Buffer sample rate', @@ -482,6 +472,60 @@ def parse_offset_get(s): self._buffer2_ready = False self.connect_message() + + + SNAP_PARAMETERS = { + 'x': '1', + 'y': '2', + 'r': '3', + 'p': '4', + 'phase': '4', + 'θ' : '4', + 'aux 1': '5', + 'aux 2': '6', + 'aux 3': '7', + 'aux 4': '8', + 'freq': '9', + 'ch 1': '10', + 'ch 2': '11' + } + + def snap(self, *parameter_names: str) -> Tuple[float, ...]: + """ + Gets the values of either 2, 3, 4, 5 or 6 parameters at a single instant. + For example, SNAP? is a way to query values of + X and Y (or R and θ) which are taken at the same time. This is important + when the time constant is very short. Using the OUTP? or OUTR? com- + mands will result in time delays, which may be greater than the time con- + stant, between reading X and Y (or R and θ) + Thus reading X,Y OR R,θ yields a coherent snapshot of the output signal. + + Args: + *parameter_names + 2 or 3 names of parameters for which the values are + requested; valid names can be found in `PARAMETER_NAMES` + attribute of the driver class + Returns: + a tuple of floating point values + + Examples: + lockin.snap('x','y') -> tuple(x,y) + lockin.snap('aux 1','aux 2','freq','phase') -> tuple(aux1,aux2,freq,phase) + """ + if not 2 <= len(parameter_names) <= 6: + raise KeyError( + 'It is only possible to request values of 2 to 6 parameters ' + 'at a time.') + + for name in parameter_names: + if name.lower() not in self.SNAP_PARAMETERS: + raise KeyError(f'{name} is not a valid parameter name. Refer ' + f'to `SNAP_PARAMETERS` for a list of valid ' + f'parameter names') + + p_ids = [self.PARAMETER_NAMES[name.lower()] for name in parameter_names] + output = self.ask(f'SNAP? {",".join(p_ids)}') + return tuple(float(val) for val in output.split(',')) def _set_buffer_SR(self, SR): self.write('SRAT {}'.format(SR)) From aa07256ba29ade66fc170f9b16f5231775e7eabf Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Thu, 25 Oct 2018 14:06:33 +0200 Subject: [PATCH 026/719] Update SR830.py Rewritten the doc string cleaning up the text. Removed all notions of visa commands. Removed space from 'aux 4' -> 'aux4' and similar in the SNAP_PARAMETERS. All lines are less than 80 characters long. To follow PEP8. Fixed typos. --- .../stanford_research/SR830.py | 98 +++++++++++-------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 68d9d45f4ac..07859286b26 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -481,51 +481,67 @@ def parse_offset_get(s): 'p': '4', 'phase': '4', 'θ' : '4', - 'aux 1': '5', - 'aux 2': '6', - 'aux 3': '7', - 'aux 4': '8', + 'aux1': '5', + 'aux2': '6', + 'aux3': '7', + 'aux4': '8', 'freq': '9', - 'ch 1': '10', - 'ch 2': '11' + 'ch1': '10', + 'ch2': '11' } - def snap(self, *parameter_names: str) -> Tuple[float, ...]: - """ - Gets the values of either 2, 3, 4, 5 or 6 parameters at a single instant. - For example, SNAP? is a way to query values of - X and Y (or R and θ) which are taken at the same time. This is important - when the time constant is very short. Using the OUTP? or OUTR? com- - mands will result in time delays, which may be greater than the time con- - stant, between reading X and Y (or R and θ) - Thus reading X,Y OR R,θ yields a coherent snapshot of the output signal. - - Args: - *parameter_names - 2 or 3 names of parameters for which the values are - requested; valid names can be found in `PARAMETER_NAMES` - attribute of the driver class - Returns: - a tuple of floating point values - - Examples: - lockin.snap('x','y') -> tuple(x,y) - lockin.snap('aux 1','aux 2','freq','phase') -> tuple(aux1,aux2,freq,phase) + def snap(self, *parameters: str) -> Tuple[float, ...]: + """ +Get between 2 and 6 parameters at a single instant. This provides a coherent +snapshot of measured signals. Pick up to 6 from: X, Y, R, θ, the aux +inputs 1-4, frequency, or what is currently displayed on channels 1 and 2. +Reading X and Y (or R and θ) gives a coherent snapshot of the signal. +Snap is important when the time constant is very short, a time constant less +than 100 ms. + +Args: + *parameters + From 2 to 6 strings of names of parameters for which the values are + requested. including: 'x', 'y', 'r', 'p', 'phase' or 'θ', + 'aux1', 'aux2', 'aux3', 'aux4', 'freq', 'ch1', and 'ch2'. + +Returns: + A tuple of floating point values in the same order as requested. + +Units: + Volts for x, y, r, and aux 1-4 + Degrees for θ + Hertz for freq + Unknown for ch1 and ch2. It will depend on what was set. + +Examples: + lockin.snap('x','y') -> tuple(x,y) + + lockin.snap('aux1','aux2','freq','phase') + -> tuple(aux1,aux2,freq,phase) + +Limitations: + - If X,Y,R and θ are all read, then the values of X,Y are recorded + approximately 10 µs apart from R,θ. Thus, the values of X and Y may not + yield the exact values of R and θ from a single snap. + - The values of the Aux Inputs may have an uncertainty of up to 32 µs. + - The frequency is computed only every other period or 40 ms, whichever is + longer. """ - if not 2 <= len(parameter_names) <= 6: - raise KeyError( - 'It is only possible to request values of 2 to 6 parameters ' - 'at a time.') - - for name in parameter_names: - if name.lower() not in self.SNAP_PARAMETERS: - raise KeyError(f'{name} is not a valid parameter name. Refer ' - f'to `SNAP_PARAMETERS` for a list of valid ' - f'parameter names') - - p_ids = [self.PARAMETER_NAMES[name.lower()] for name in parameter_names] - output = self.ask(f'SNAP? {",".join(p_ids)}') - return tuple(float(val) for val in output.split(',')) + if not 2 <= len(parameters) <= 6: + raise KeyError( + 'It is only possible to request values of 2 to 6 parameters' + ' at a time.') + + for name in parameters: + if name.lower() not in self.SNAP_PARAMETERS: + raise KeyError(f'{name} is an unknown parameter. Refer' + f' to `SNAP_PARAMETERS` for a list of valid' + f' parameter names') + + p_ids = [self.SNAP_PARAMETERS[name.lower()] for name in parameters] + output = self.ask(f'SNAP? {",".join(p_ids)}') + return tuple(float(val) for val in output.split(',')) def _set_buffer_SR(self, SR): self.write('SRAT {}'.format(SR)) From fe42007ee301b0e0c094a311ee643a8c297f6179 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 1 Nov 2018 18:40:09 +0100 Subject: [PATCH 027/719] Make ParamSpec hashable (implement __hash__) --- qcodes/dataset/param_spec.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/qcodes/dataset/param_spec.py b/qcodes/dataset/param_spec.py index 3dce28f3ca2..d10473dc067 100644 --- a/qcodes/dataset/param_spec.py +++ b/qcodes/dataset/param_spec.py @@ -105,6 +105,26 @@ def __eq__(self, other): return False return True + def __hash__(self) -> int: + """Allow ParamSpecs in data structures that use hashing (i.e. sets)""" + attrs_with_strings = ['name', 'type', 'label', 'unit'] + attrs_with_lists = ['_inferred_from', '_depends_on'] + + # First, get the hash of the tuple with all the relevant attributes + all_attr_tuple_hash = hash( + tuple(getattr(self, attr) for attr in attrs_with_strings) + + tuple(tuple(getattr(self, attr)) for attr in attrs_with_lists) + ) + hash_value = all_attr_tuple_hash + + # Then, XOR it with the individual hashes of all relevant attributes + for attr in attrs_with_strings: + hash_value = hash_value ^ hash(getattr(self, attr)) + for attr in attrs_with_lists: + hash_value = hash_value ^ hash(tuple(getattr(self, attr))) + + return hash_value + def serialize(self) -> Dict[str, Any]: """ Write the ParamSpec as a dictionary From 513149fd1e516e60d0ffc1370fb24916423ac314 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 1 Nov 2018 18:41:02 +0100 Subject: [PATCH 028/719] Test ParamSpec hashing with hypothesis --- qcodes/tests/dataset/test_paramspec.py | 94 +++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_paramspec.py b/qcodes/tests/dataset/test_paramspec.py index 1a573128ce4..016792ad484 100644 --- a/qcodes/tests/dataset/test_paramspec.py +++ b/qcodes/tests/dataset/test_paramspec.py @@ -1,6 +1,7 @@ -import pytest +from keyword import iskeyword from numbers import Number +import pytest from numpy import ndarray from hypothesis import given import hypothesis.strategies as hst @@ -8,6 +9,30 @@ from qcodes.dataset.param_spec import ParamSpec +@hst.defines_strategy +def valid_identifier(**kwargs): + """Return a strategy which generates a valid Python Identifier""" + if 'min_size' not in kwargs: + kwargs['min_size'] = 4 + return hst.text( + alphabet="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", + **kwargs).filter( + lambda x: x[0].isalpha() and x.isidentifier() and not (iskeyword(x)) + ) + + +# This strategy generates a dict of kwargs needed to instantiate a valid +# ParamSpec object +valid_paramspec_kwargs = hst.fixed_dictionaries( + {'name': valid_identifier(min_size=1), + 'paramtype': hst.sampled_from(['numeric', 'array', 'text']), + 'label': hst.one_of(hst.none(), hst.text()), + 'unit': hst.one_of(hst.none(), hst.text()), + 'depends_on': hst.lists(hst.text(min_size=1), min_size=0), + 'inferred_from': hst.lists(hst.text(min_size=1), min_size=0) + }) + + @pytest.fixture def version_0_serializations(): sers = [] @@ -162,7 +187,6 @@ def test_copy(name1, name2, name3): def test_serialize(): - p1 = ParamSpec('p1', 'numeric', 'paramspec one', 'no unit', depends_on=['some', 'thing'], inferred_from=['bab', 'bob']) @@ -177,7 +201,71 @@ def test_serialize(): def test_deserialize(version_0_serializations, version_0_deserializations): - for sdict, ps in zip(version_0_serializations, version_0_deserializations): deps = ParamSpec.deserialize(sdict) assert ps == deps + + +@given(paramspecs=hst.lists(valid_paramspec_kwargs, min_size=2, max_size=2)) +def test_hash(paramspecs): + p1 = ParamSpec(**paramspecs[0]) + p2 = ParamSpec(**paramspecs[1]) + + # call __hash__ + p1_h = hash(p1) + p2_h = hash(p2) + + # make a set + p_set = {p1, p2} + + # test that the hash equality follows object equality + if p1 == p2: + assert p1_h == p2_h + assert 1 == len(p_set) + else: + assert p1_h != p2_h + assert 2 == len(p_set) + + +@given(paramspecs=hst.lists(valid_paramspec_kwargs, min_size=6, max_size=6), + add_to_1_inf=hst.booleans(), + add_to_1_dep=hst.booleans(), + add_to_2_inf=hst.booleans(), + add_to_2_dep=hst.booleans(), + ) +def test_hash_with_deferred_and_inferred_as_paramspecs( + paramspecs, add_to_1_inf, add_to_1_dep, add_to_2_inf, add_to_2_dep): + """ + Test that hashing works if 'inferred_from' and/or 'depend_on' contain + actual ParamSpec instances and not just strings. + """ + hst.assume(add_to_1_inf or add_to_1_dep or add_to_2_inf or add_to_2_dep) + + # Add ParamSpecs to 'inferred_from' and/or 'depend_on' lists next to + # strings (that are generated by the main strategy) + if add_to_1_inf: + paramspecs[0]['inferred_from'].append(ParamSpec(**paramspecs[2])) + if add_to_1_dep: + paramspecs[0]['depends_on'].append(ParamSpec(**paramspecs[3])) + if add_to_2_inf: + paramspecs[1]['inferred_from'].append(ParamSpec(**paramspecs[4])) + if add_to_2_dep: + paramspecs[1]['depends_on'].append(ParamSpec(**paramspecs[5])) + + p1 = ParamSpec(**paramspecs[0]) + p2 = ParamSpec(**paramspecs[1]) + + # call __hash__ + p1_h = hash(p1) + p2_h = hash(p2) + + # make a set + p_set = {p1, p2} + + # test that the hash equality follows object equality + if p1 == p2: + assert p1_h == p2_h + assert 1 == len(p_set) + else: + assert p1_h != p2_h + assert 2 == len(p_set) From 8aa94f45bb757633f88e9a4f7769483c29762787 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 1 Nov 2018 18:41:24 +0100 Subject: [PATCH 029/719] Test hashes of equal/copied ParamSpecs explicitly --- qcodes/tests/dataset/test_paramspec.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_paramspec.py b/qcodes/tests/dataset/test_paramspec.py index 016792ad484..fc6bbeb71a9 100644 --- a/qcodes/tests/dataset/test_paramspec.py +++ b/qcodes/tests/dataset/test_paramspec.py @@ -158,15 +158,16 @@ def test_add_inferred_from(name1, name2, name3): @given( name1=hst.text(min_size=4, alphabet=alphabet), - name2=hst.text(min_size=4, alphabet=alphabet), - name3=hst.text(min_size=4, alphabet=alphabet), + name2=hst.text(min_size=4, alphabet=alphabet) ) -def test_copy(name1, name2, name3): - +def test_copy(name1, name2): ps_indep = ParamSpec(name1, "numeric") - ps = ParamSpec(name3, "numeric", depends_on=[ps_indep]) + ps = ParamSpec(name2, "numeric", depends_on=[ps_indep, 'other_param']) ps_copy = ps.copy() + assert ps_copy == ps + assert hash(ps_copy) == hash(ps) + att_names = ["name", "type", "label", "unit", "_inferred_from", "_depends_on"] @@ -185,6 +186,9 @@ def test_copy(name1, name2, name3): setattr(ps_copy, att, attributes[att] + ['bob']) assert getattr(ps, att) == attributes[att] + assert ps_copy != ps + assert hash(ps_copy) != hash(ps) + def test_serialize(): p1 = ParamSpec('p1', 'numeric', 'paramspec one', 'no unit', From 89520f4bcf5988f1b28201eec8d3552769a60506 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 13 Nov 2018 10:56:32 +0100 Subject: [PATCH 030/719] make import of legume conditional --- qcodes/instrument_drivers/tektronix/AWG5014.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index a66297d5d3e..fce55e8a328 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -19,7 +19,12 @@ from qcodes.utils.deprecate import deprecate from pyvisa.errors import VisaIOError -from broadbean.tools import is_subsequence, get_element_channel_ids +# conditionally import legume for support of legume type sequences +try: + from legume.tools import is_subsequence, get_element_channel_ids + USE_LEGUME = True +except ImportError: + USE_LEGUME = False log = logging.getLogger(__name__) @@ -1061,6 +1066,10 @@ def make_send_and_load_awg_file_from_forged_sequence( preservechannelsettings: see :meth:`~make_send_and_load_awg_file` """ + if not USE_LEGUME: + raise RuntimeError( + 'The method "make_send_and_load_awg_file_from_forged_sequence" is ' + ' only available with the `legume` module installed') n_channels = 4 self.available_waveform_channels = list(range(1, n_channels+1)) self.available_marker_channels = [ From 0576efecffa3ba40022e7daae7fe384ae1d69099 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Tue, 13 Nov 2018 12:15:50 +0100 Subject: [PATCH 031/719] rename legume->lomentum --- qcodes/instrument_drivers/tektronix/AWG5014.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index fce55e8a328..3b36f40cf2b 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -19,12 +19,12 @@ from qcodes.utils.deprecate import deprecate from pyvisa.errors import VisaIOError -# conditionally import legume for support of legume type sequences +# conditionally import lomentum for support of lomentum type sequences try: - from legume.tools import is_subsequence, get_element_channel_ids - USE_LEGUME = True + from lomentum.tools import is_subsequence, get_element_channel_ids + USE_LOMENTUM = True except ImportError: - USE_LEGUME = False + USE_LOMENTUM = False log = logging.getLogger(__name__) @@ -1066,10 +1066,10 @@ def make_send_and_load_awg_file_from_forged_sequence( preservechannelsettings: see :meth:`~make_send_and_load_awg_file` """ - if not USE_LEGUME: + if not USE_LOMENTUM: raise RuntimeError( 'The method "make_send_and_load_awg_file_from_forged_sequence" is ' - ' only available with the `legume` module installed') + ' only available with the `lomentum` module installed') n_channels = 4 self.available_waveform_channels = list(range(1, n_channels+1)) self.available_marker_channels = [ From 063c15acf38c8b1b40f262b66865b2c6ab149235 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 24 Oct 2018 15:54:52 +0200 Subject: [PATCH 032/719] Add very rudimentary copy-paste module --- qcodes/dataset/database_copy_paste.py | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 qcodes/dataset/database_copy_paste.py diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py new file mode 100644 index 00000000000..41e82ee0451 --- /dev/null +++ b/qcodes/dataset/database_copy_paste.py @@ -0,0 +1,81 @@ +from qcodes.dataset.data_set import DataSet +from qcodes.dataset.sqlite_base import (atomic, + connect, + get_last_experiment, + insert_column, + SomeConnection) + + +def copy_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: + """ + Insert the given dataset into the specified database file as the latest + run. The database file must exist and its latest experiment must have name + and sample_name matching that of the dataset's parent experiment + + Args: + dataset: A dataset representing the run to be copied + path_to_db: The path to the target DB into which the run should be + inserted + """ + + if not dataset.completed: + raise ValueError('Dataset not completed. An incomplete dataset ' + 'can not be copied.') + + source_conn = dataset.conn + target_conn = connect(path_to_db) + + exp_id = get_last_experiment(target_conn) + + with atomic(target_conn) as target_conn: + _copy_runs_table_entries(source_conn, + target_conn, + dataset.run_id, + exp_id) + + +def _copy_runs_table_entries(source_conn: SomeConnection, + target_conn: SomeConnection, + source_run_id: int, + target_exp_id: int) -> None: + """ + Copy an entire runs table row from one DB and paste it all + (expect the primary key) into another DB. The two DBs may be the same. + + This function should be executed with an atomically guarded target_conn + as a part of a larger atomic transaction + """ + runs_row_query = """ + SELECT * + FROM runs + WHERE run_id = ? + """ + cursor = source_conn.cursor() + cursor.execute(runs_row_query, (source_run_id,)) + source_runs_row = cursor.fetchall()[0] + source_colnames = set(source_runs_row.keys()) + + # There might not be any runs in the target DB, hence we ask PRAGMA + cursor = target_conn.cursor() + cursor.execute("PRAGMA table_info(runs)", ()) + tab_info = cursor.fetchall() + target_colnames = set([r['name'] for r in tab_info]) + + for colname in source_colnames.difference(target_colnames): + insert_column(target_conn, 'runs', colname) + + # the first entry is "run_id" + sql_colnames = str(tuple(source_runs_row.keys()[1:])).replace("'", "") + sql_placeholders = '(' + ','.join('?'*len(sql_colnames)) + ')' + + sql_insert_values = f""" + INSERT INTO runs + {sql_colnames} + VALUES + {sql_placeholders} + """ + # the first two entries in source_runs_row are run_id and exp_id + values = tuple([exp_id] + [val for val in source_runs_row[2:]]) + + cursor = target_conn.cursor() + cursor.execute(sql_insert_values, values) \ No newline at end of file From bb51e60f7431b42af141ec560a4fd69cf9b72996 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 25 Oct 2018 11:03:29 +0200 Subject: [PATCH 033/719] Add sql_placeholder_string function --- qcodes/dataset/database_copy_paste.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 41e82ee0451..87c366854d0 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -5,6 +5,11 @@ insert_column, SomeConnection) +def sql_placeholder_string(n: int) -> str: + """ + Return an SQL placeholder string of length n. + """ + return '(' + ','.join('?'*n) + ')' def copy_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: """ From 89a45807106076381a54bec3a4366017fabc286d Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 25 Oct 2018 12:52:25 +0200 Subject: [PATCH 034/719] Make Experiment take a connection and use that in funcs --- qcodes/dataset/experiment_container.py | 46 +++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index 36ccdc69dcd..08b3653cb3c 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -12,7 +12,8 @@ connect, transaction, get_last_experiment, get_experiments, get_experiment_name_from_experiment_id, - get_sample_name_from_experiment_id) + get_sample_name_from_experiment_id, + SomeConnection) from qcodes.dataset.sqlite_base import new_experiment as ne from qcodes.dataset.database import get_DB_location, get_DB_debug @@ -25,7 +26,8 @@ def __init__(self, path_to_db: Optional[str]=None, exp_id: Optional[int]=None, name: Optional[str]=None, sample_name: Optional[str]=None, - format_string: str="{}-{}-{}") -> None: + format_string: str="{}-{}-{}", + conn: Optional[SomeConnection]=None) -> None: """ Create or load an experiment. If exp_id is None, a new experiment is created. If exp_id is not None, an experiment is loaded. @@ -39,9 +41,11 @@ def __init__(self, path_to_db: Optional[str]=None, is not None format_string: The format string used to name result-tables. Ignored if exp_id is not None. + conn: connection to the database. If not supplied, a new connection + to the DB file specified in the config is made """ self._path_to_db = path_to_db or get_DB_location() - self.conn = connect(self.path_to_db, get_DB_debug()) + self.conn = conn or connect(self.path_to_db, get_DB_debug()) max_id = len(get_experiments(self.conn)) @@ -186,7 +190,8 @@ def experiments()->List[Experiment]: def new_experiment(name: str, sample_name: str, - format_string: Optional[str] = "{}-{}-{}") -> Experiment: + format_string: Optional[str]="{}-{}-{}", + conn: Optional[SomeConnection]=None) -> Experiment: """ Create a new experiment (in the database file from config) @@ -195,11 +200,15 @@ def new_experiment(name: str, sample_name: the name of the current sample format_string: basic format string for table-name must contain 3 placeholders. + conn: connection to the database. If not supplied, a new connection + to the DB file specified in the config is made Returns: the new experiment """ + conn = conn or connect(get_DB_location()) return Experiment(name=name, sample_name=sample_name, - format_string=format_string) + format_string=format_string, + conn=conn) def load_experiment(exp_id: int) -> Experiment: @@ -231,7 +240,8 @@ def load_last_experiment() -> Experiment: def load_experiment_by_name(name: str, - sample: Optional[str] = None) -> Experiment: + sample: Optional[str] = None, + conn: Optional[SomeConnection]=None) -> Experiment: """ Try to load experiment with the specified name. @@ -241,6 +251,8 @@ def load_experiment_by_name(name: str, Args: name: the name of the experiment sample: the name of the sample + conn: connection to the database. If not supplied, a new connection + to the DB file specified in the config is made Returns: the requested experiment @@ -248,7 +260,8 @@ def load_experiment_by_name(name: str, Raises: ValueError if the name is not unique and sample name is None. """ - conn = connect(get_DB_location()) + conn = conn or connect(get_DB_location()) + if sample: sql = """ SELECT @@ -288,26 +301,29 @@ def load_experiment_by_name(name: str, def load_or_create_experiment(experiment_name: str, - sample_name: Optional[str] = None - ) -> Experiment: + sample_name: Optional[str] = None, + conn: Optional[SomeConnection]=None)->Experiment: """ Find and return an experiment with the given name and sample name, or create one if not found. Args: - experiment_name - Name of the experiment to find or create - sample_name - Name of the sample + experiment_name: Name of the experiment to find or create + sample_name: Name of the sample + conn: Connection to the database. If not supplied, a new connection + to the DB file specified in the config is made Returns: The found or created experiment """ + conn = conn or connect(get_DB_location()) try: - experiment = load_experiment_by_name(experiment_name, sample_name) + experiment = load_experiment_by_name(experiment_name, sample_name, + conn=conn) except ValueError as exception: if "Experiment not found" in str(exception): - experiment = new_experiment(experiment_name, sample_name) + experiment = new_experiment(experiment_name, sample_name, + conn=conn) else: raise exception return experiment From 3d98f5856f5ec9504f275a0c910d269eb6cac911 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 24 Oct 2018 16:39:56 +0200 Subject: [PATCH 035/719] Add first partial copy function --- qcodes/dataset/database_copy_paste.py | 71 +++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 87c366854d0..e11f902bc62 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -1,17 +1,82 @@ +import numpy as np + from qcodes.dataset.data_set import DataSet +from qcodes.dataset.experiment_container import load_or_create_experiment from qcodes.dataset.sqlite_base import (atomic, connect, get_last_experiment, insert_column, SomeConnection) + def sql_placeholder_string(n: int) -> str: """ Return an SQL placeholder string of length n. """ return '(' + ','.join('?'*n) + ')' -def copy_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: + +def copy_runs_into_db(source_db_path: str, + target_db_path: str, *run_ids) -> None: + """ + Copy a selection of runs into another DB file. All runs must come from the + same experiment. They will be added to an experiment with the same name + and sample_name in the target db. If such an experiment does not exist, + it will be created. + + Args: + source_db_path: Path to the source DB file + target_db_path: Path to the target DB file + run_ids: The run_ids of the runs to copy into the target DB file + """ + + # Validate that all runs are from the same experiment + + sql_placeholders = sql_placeholder_string(len(run_ids)) + exp_id_query = f""" + SELECT exp_id + FROM runs + WHERE run_id IN {sql_placeholders} + """ + source_conn = connect(source_db_path) + cursor = source_conn.cursor() + cursor.execute(exp_id_query, run_ids) + rows = cursor.fetchall() + source_exp_ids = np.unique([exp_id for row in rows for exp_id in row]) + if len(source_exp_ids) != 1: + raise ValueError('Did not receive runs from a single experiment. ' + f'Got runs from experiments {source_exp_ids}') + + # Fetch the name and sample name of the runs' experiment + + names_query = """ + SELECT name, sample_name + FROM experiments + WHERE exp_id = ? + """ + cursor = source_conn.cursor() + cursor.execute(names_query, (source_exp_ids[0],)) + row = cursor.fetchall()[0] + (source_exp_name, source_sample_name) = (row['name'], row['sample_name']) + + # Massage the target DB file to accomodate the runs + # (create new experiment if needed) + + target_conn = connect(target_db_path) + + # this function raises if the target DB file has several experiments + # matching both the name and sample_name + + load_or_create_experiment(source_exp_name, source_sample_name, + conn=target_conn) + + # Finally insert the runs + for run_id in run_ids: + copy_single_dataset_into_db(DataSet(run_id=run_id, conn=source_conn), + target_db_path) + + +def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: """ Insert the given dataset into the specified database file as the latest run. The database file must exist and its latest experiment must have name @@ -71,7 +136,7 @@ def _copy_runs_table_entries(source_conn: SomeConnection, # the first entry is "run_id" sql_colnames = str(tuple(source_runs_row.keys()[1:])).replace("'", "") - sql_placeholders = '(' + ','.join('?'*len(sql_colnames)) + ')' + sql_placeholders = sql_placeholder_string(len(source_runs_row.keys())-1) sql_insert_values = f""" INSERT INTO runs @@ -80,7 +145,7 @@ def _copy_runs_table_entries(source_conn: SomeConnection, {sql_placeholders} """ # the first two entries in source_runs_row are run_id and exp_id - values = tuple([exp_id] + [val for val in source_runs_row[2:]]) + values = tuple([target_exp_id] + [val for val in source_runs_row[2:]]) cursor = target_conn.cursor() cursor.execute(sql_insert_values, values) \ No newline at end of file From de60f6bd6de661e569962e5bb6cba406f4203433 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 25 Oct 2018 15:19:57 +0200 Subject: [PATCH 036/719] Protect copy_single_dataset against inserting duplicates --- qcodes/dataset/database_copy_paste.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index e11f902bc62..992c7dc317d 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -95,6 +95,17 @@ def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: source_conn = dataset.conn target_conn = connect(path_to_db) + already_in_query = """ + SELECT run_id + FROM runs + WHERE guid = ? + """ + cursor = target_conn.cursor() + cursor.execute(already_in_query, (dataset.guid,)) + res = cursor.fetchall() + if len(res) > 0: + return + exp_id = get_last_experiment(target_conn) with atomic(target_conn) as target_conn: From 6f7b0b748ee810b91b7fe2a2936c94dc8d15bf4f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 26 Oct 2018 10:27:24 +0200 Subject: [PATCH 037/719] Add experiment table update to run copy --- qcodes/dataset/database_copy_paste.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 992c7dc317d..97c967242a9 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -113,6 +113,7 @@ def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: target_conn, dataset.run_id, exp_id) + _update_run_counter(target_conn, exp_id) def _copy_runs_table_entries(source_conn: SomeConnection, @@ -159,4 +160,14 @@ def _copy_runs_table_entries(source_conn: SomeConnection, values = tuple([target_exp_id] + [val for val in source_runs_row[2:]]) cursor = target_conn.cursor() - cursor.execute(sql_insert_values, values) \ No newline at end of file + cursor.execute(sql_insert_values, values) + + +def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: + update_sql = """ + UPDATE experiments + SET run_counter = run_counter + 1 + WHERE exp_id = ? + """ + cursor = target_conn.cursor() + cursor.execute(update_sql, (target_exp_id,)) \ No newline at end of file From 01b2579960af52322686d994cae1d88d826453d5 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 26 Oct 2018 16:37:06 +0200 Subject: [PATCH 038/719] Add basic database copy_paste test --- qcodes/tests/dataset/temporary_databases.py | 12 ++++++++++ .../tests/dataset/test_database_copy_paste.py | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 qcodes/tests/dataset/test_database_copy_paste.py diff --git a/qcodes/tests/dataset/temporary_databases.py b/qcodes/tests/dataset/temporary_databases.py index 2d8d1ca3cae..e60c6dc997c 100644 --- a/qcodes/tests/dataset/temporary_databases.py +++ b/qcodes/tests/dataset/temporary_databases.py @@ -25,6 +25,18 @@ def empty_temp_db(): yield +@pytest.fixture(scope='function') +def two_empty_temp_dbs(): + """ + Yield the paths of two empty files. Meant for use with the + test_database_copy_paste + """ + with tempfile.TemporaryDirectory() as tmpdirname: + source_path = os.path.join(tmpdirname, 'source.db') + target_path = os.path.join(tmpdirname, 'target.db') + yield (source_path, target_path) + + @pytest.fixture(scope='function') def experiment(empty_temp_db): e = new_experiment("test-experiment", sample_name="test-sample") diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py new file mode 100644 index 00000000000..c1877b949c3 --- /dev/null +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -0,0 +1,22 @@ +import pytest + +from qcodes.dataset.sqlite_base import connect +from qcodes.dataset.experiment_container import Experiment +from qcodes.dataset.data_set import DataSet +from qcodes.dataset.database_copy_paste import copy_runs_into_db +from qcodes.tests.dataset.temporary_databases import two_empty_temp_dbs + + +def test_basic_copy_paste(two_empty_temp_dbs): + source_path, target_path = two_empty_temp_dbs + + source_conn = connect(source_path) + target_conn = connect(target_path) + + exp = Experiment(conn=source_conn) + dataset = DataSet(conn=source_conn) + + with pytest.raises(ValueError, match='Dataset not completed'): + copy_runs_into_db(source_path, target_path, dataset.run_id) + + From 78e767bb26798552b62257ec9c7c90f15b7dbec3 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Sat, 27 Oct 2018 15:31:29 +0200 Subject: [PATCH 039/719] Add complete single run copy function --- qcodes/dataset/database_copy_paste.py | 152 +++++++++++++++++- .../tests/dataset/test_database_copy_paste.py | 19 ++- 2 files changed, 168 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 97c967242a9..083f0583059 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -4,6 +4,7 @@ from qcodes.dataset.experiment_container import load_or_create_experiment from qcodes.dataset.sqlite_base import (atomic, connect, + format_table_name, get_last_experiment, insert_column, SomeConnection) @@ -114,6 +115,12 @@ def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: dataset.run_id, exp_id) _update_run_counter(target_conn, exp_id) + _copy_layouts_and_dependencies(source_conn, + target_conn, + dataset.run_id) + _copy_results_table(source_conn, + target_conn, + dataset.run_id) def _copy_runs_table_entries(source_conn: SomeConnection, @@ -122,7 +129,8 @@ def _copy_runs_table_entries(source_conn: SomeConnection, target_exp_id: int) -> None: """ Copy an entire runs table row from one DB and paste it all - (expect the primary key) into another DB. The two DBs may be the same. + (expect the primary key) into another DB. The two DBs may not be the same. + Note that this function does not create a new results table This function should be executed with an atomically guarded target_conn as a part of a larger atomic transaction @@ -164,10 +172,150 @@ def _copy_runs_table_entries(source_conn: SomeConnection, def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: + """ + Update the run_counter in the target DB experiments table + """ update_sql = """ UPDATE experiments SET run_counter = run_counter + 1 WHERE exp_id = ? """ cursor = target_conn.cursor() - cursor.execute(update_sql, (target_exp_id,)) \ No newline at end of file + cursor.execute(update_sql, (target_exp_id,)) + + +def _copy_layouts_and_dependencies(target_conn: SomeConnection, + source_conn: SomeConnection, + source_run_id: int) -> None: + """ + Copy over the layouts and dependencies tables. Note that the layout_ids + are not preserved in the target DB, but of course their relationships are + (e.g. layout_id 10 that depends on layout_id 9 might be inserted as + layout_id 2 that depends on layout_id 1) + """ + layout_query = """ + SELECT layout_id, run_id, parameter, label, unit, inferred_from + FROM layouts + WHERE run_id = ? + """ + cursor = source_conn.cursor() + cursor.execute(layout_query, (source_run_id,)) + rows = cursor.fetchall() + + layout_insert = """ + INSERT INTO layouts + (run_id, parameter, label, unit, inferred_from) + VALUES (?,?,?,?,?) + """ + + colnames = ('run_id', 'parameter', 'label', 'unit', 'inferred_from') + cursor = target_conn.cursor() + source_layout_ids = [] + target_layout_ids = [] + for row in rows: + values = tuple(row[colname] for colname in colnames) + cursor.execute(layout_insert, values) + source_layout_ids.append(row['layout_id']) + target_layout_ids.append(cursor.lastrowid) + + # for the dependencies, we need a map from source layout_id to + # target layout_id + layout_id_map = dict(zip(source_layout_ids, target_layout_ids)) + + placeholders = sql_placeholder_string(len(source_layout_ids)) + + deps_query = f""" + SELECT dependent, independent, axis_num + FROM dependencies + WHERE dependent IN {placeholders} + OR independent IN {placeholders} + """ + + cursor = source_conn.cursor() + cursor.execute(deps_query, tuple(source_layout_ids*2)) + rows = cursor.fetchall() + + deps_insert = """ + INSERT INTO dependencies + (dependent, independent, axis_num) + VALUES (?,?,?) + """ + cursor = target_conn.cursor() + + for row in rows: + values = (layout_id_map[row['dependent']], + layout_id_map[row['independent']], + row['axis_num']) + cursor.execute(deps_insert, values) + + +def _copy_results_table(source_conn: SomeConnection, + target_conn: SomeConnection, + source_run_id) -> None: + """ + Copy the contents of the results table. Creates a new results_table with + a name appropriate for the target DB and updates the + """ + table_name_query = """ + SELECT result_table_name, name + FROM runs + WHERE run_id = ? + """ + cursor = source_conn.cursor() + cursor.execute(table_name_query, (source_run_id,)) + row = cursor.fetchall()[0] + table_name = row['result_table_name'] + run_name = row['name'] + + format_string_query = """ + SELECT format_string, run_counter, experiments.exp_id + FROM experiments + INNER JOIN runs + ON runs.exp_id = experiments.exp_id + WHERE runs.run_id = ? + """ + cursor.execute(format_string_query, (source_run_id,)) + row = cursor.fetchall()[0] + format_string = row['format_string'] + run_counter = row['run_counter'] + exp_id = int(row['exp_id']) + + get_data_query = f""" + SELECT * + FROM "{table_name}" + """ + + cursor.execute(get_data_query) + data_rows = cursor.fetchall() + data_columns = data_rows[0].keys() + data_columns.remove('id') + + target_table_name = format_table_name(format_string, + run_name, + exp_id, + run_counter) + + column_names = ','.join(data_columns) + make_table = f""" + CREATE TABLE "{target_table_name}" ( + id INTEGER PRIMARY KEY, + {column_names} + ) + """ + + cursor = target_conn.cursor() + cursor.execute(make_table) + + # according to one of our reports, multiple single-row inserts + # are okay if there's only one commit + + value_placeholders = sql_placeholder_string(len(data_columns)) + insert_data = f""" + INSERT INTO "{target_table_name}" + ({column_names}) + values {value_placeholders} + """ + + for row in data_rows: + # the first row entry is the ID, which is automatically inserted + cursor.execute(insert_data, tuple(v for v in row[1:])) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index c1877b949c3..3d68c9479db 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -1,15 +1,22 @@ import pytest +import numpy as np from qcodes.dataset.sqlite_base import connect from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import DataSet from qcodes.dataset.database_copy_paste import copy_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_dbs +from qcodes.tests.dataset.test_descriptions import some_paramspecs -def test_basic_copy_paste(two_empty_temp_dbs): +def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): source_path, target_path = two_empty_temp_dbs + type_casters = {'numeric': float, + 'array': (lambda x: np.array(x) if hasattr(x, '__iter__') + else np.array([x])), + 'text': str} + source_conn = connect(source_path) target_conn = connect(target_path) @@ -19,4 +26,14 @@ def test_basic_copy_paste(two_empty_temp_dbs): with pytest.raises(ValueError, match='Dataset not completed'): copy_runs_into_db(source_path, target_path, dataset.run_id) + for ps in some_paramspecs[1].values(): + dataset.add_parameter(ps) + + value = 0 # an arbitrary data value + result = {ps.name: type_casters[ps.type](value) + for ps in some_paramspecs[1].values()} + + dataset.add_result(result) + dataset.mark_complete() + copy_runs_into_db(source_path, target_path, dataset.run_id) From 2c04cac34a612266505f3ab1ce46a3a846f2f6f8 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 13:01:07 +0100 Subject: [PATCH 040/719] Refactor table name formatting into function --- qcodes/dataset/sqlite_base.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 00dc00be102..3b2930ea399 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1515,6 +1515,22 @@ def data_sets(conn: SomeConnection) -> List[sqlite3.Row]: return c.fetchall() +def format_table_name(fmt_str: str, name: str, exp_id: int, + run_counter: int) -> str: + """ + Format the format_string into a table name + + Args: + fmt_str: a valid format string + name: the run name + exp_id: the experiment ID + run_counter: the intra-experiment runnumber of this run + """ + table_name = fmt_str.format(name, exp_id, run_counter) + _validate_table_name(table_name) # raises if table_name not valid + return table_name + + def _insert_run(conn: SomeConnection, exp_id: int, name: str, guid: str, parameters: Optional[List[ParamSpec]] = None, @@ -1527,7 +1543,8 @@ def _insert_run(conn: SomeConnection, exp_id: int, name: str, where_column="exp_id", where_value=exp_id) run_counter += 1 - formatted_name = format_string.format(name, exp_id, run_counter) + formatted_name = format_table_name(format_string, name, exp_id, + run_counter) table = "runs" parameters = parameters or [] From 52f5a8892325d5f7b57cff9b5040e6b1f7ea6b20 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 14:09:45 +0100 Subject: [PATCH 041/719] Extend test to test for dataset equility --- .../tests/dataset/test_database_copy_paste.py | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 3d68c9479db..c68e52f03b9 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -20,20 +20,47 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): source_conn = connect(source_path) target_conn = connect(target_path) - exp = Experiment(conn=source_conn) - dataset = DataSet(conn=source_conn) + source_exp = Experiment(conn=source_conn) + source_dataset = DataSet(conn=source_conn) with pytest.raises(ValueError, match='Dataset not completed'): - copy_runs_into_db(source_path, target_path, dataset.run_id) + copy_runs_into_db(source_path, target_path, source_dataset.run_id) for ps in some_paramspecs[1].values(): - dataset.add_parameter(ps) + source_dataset.add_parameter(ps) value = 0 # an arbitrary data value result = {ps.name: type_casters[ps.type](value) for ps in some_paramspecs[1].values()} - dataset.add_result(result) - dataset.mark_complete() + source_dataset.add_result(result) + source_dataset.mark_complete() - copy_runs_into_db(source_path, target_path, dataset.run_id) + copy_runs_into_db(source_path, target_path, source_dataset.run_id) + + target_exp = Experiment(conn=target_conn, exp_id=1) + + length1 = len(target_exp) + + # trying to insert the same run again should be a NOOP + copy_runs_into_db(source_path, target_path, source_dataset.run_id) + + assert len(target_exp) == length1 + + target_dataset = DataSet(conn=source_conn, run_id=1) + + # Now make the interesting comparisons: are the target objects the same as + # the source objects? + + exp_attrs = ['name', 'sample_name', 'started_at', 'finished_at', + 'format_string'] + + ds_attrs = ['name', 'table_name', 'guid', 'number_of_results', + 'counter', 'parameters', 'paramspecs', 'exp_name', + 'sample_name', 'completed', 'snapshot', 'run_timestamp_raw'] + + for ds_attr in ds_attrs: + assert getattr(source_dataset, ds_attr) == getattr(target_dataset, ds_attr) + + # for exp_attr in exp_attrs: + # assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) From eb8ee094ebe98719cc695df79b0973736779c338 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 14:15:57 +0100 Subject: [PATCH 042/719] Move atomicity further out --- qcodes/dataset/database_copy_paste.py | 50 +++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 083f0583059..7b04b00dba6 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -68,25 +68,33 @@ def copy_runs_into_db(source_db_path: str, # this function raises if the target DB file has several experiments # matching both the name and sample_name - load_or_create_experiment(source_exp_name, source_sample_name, - conn=target_conn) + with atomic(target_conn) as target_conn: + + load_or_create_experiment(source_exp_name, source_sample_name, + conn=target_conn) - # Finally insert the runs - for run_id in run_ids: - copy_single_dataset_into_db(DataSet(run_id=run_id, conn=source_conn), - target_db_path) + # Finally insert the runs + for run_id in run_ids: + _copy_single_dataset_into_db(DataSet(run_id=run_id, + conn=source_conn), + target_conn) -def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: +def _copy_single_dataset_into_db(dataset: DataSet, + target_conn: SomeConnection) -> None: """ + NB: This function should only be called from within + :meth:copy_runs_into_db + Insert the given dataset into the specified database file as the latest run. The database file must exist and its latest experiment must have name and sample_name matching that of the dataset's parent experiment + Trying to insert a run already in the DB is a NOOP. + Args: dataset: A dataset representing the run to be copied - path_to_db: The path to the target DB into which the run should be - inserted + path_to_db: connection to the DB. Must be atomically guarded """ if not dataset.completed: @@ -94,7 +102,6 @@ def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: 'can not be copied.') source_conn = dataset.conn - target_conn = connect(path_to_db) already_in_query = """ SELECT run_id @@ -109,18 +116,17 @@ def copy_single_dataset_into_db(dataset: DataSet, path_to_db: str) -> None: exp_id = get_last_experiment(target_conn) - with atomic(target_conn) as target_conn: - _copy_runs_table_entries(source_conn, - target_conn, - dataset.run_id, - exp_id) - _update_run_counter(target_conn, exp_id) - _copy_layouts_and_dependencies(source_conn, - target_conn, - dataset.run_id) - _copy_results_table(source_conn, - target_conn, - dataset.run_id) + _copy_runs_table_entries(source_conn, + target_conn, + dataset.run_id, + exp_id) + _update_run_counter(target_conn, exp_id) + _copy_layouts_and_dependencies(source_conn, + target_conn, + dataset.run_id) + _copy_results_table(source_conn, + target_conn, + dataset.run_id) def _copy_runs_table_entries(source_conn: SomeConnection, From edc32b7b9318f367a8d03116ccebad0f0be3e20e Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 15:34:02 +0100 Subject: [PATCH 043/719] Handle existing vs non-existing experiments --- qcodes/dataset/database_copy_paste.py | 77 ++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 7b04b00dba6..22862fd148a 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -1,3 +1,5 @@ +from typing import Union + import numpy as np from qcodes.dataset.data_set import DataSet @@ -48,17 +50,21 @@ def copy_runs_into_db(source_db_path: str, raise ValueError('Did not receive runs from a single experiment. ' f'Got runs from experiments {source_exp_ids}') - # Fetch the name and sample name of the runs' experiment + # Fetch the attributes of the runs' experiment + # hopefully, this is enough to uniquely identify the experiment + + exp_attr_names = ['name', 'sample_name', 'start_time', 'end_time', + 'format_string'] - names_query = """ - SELECT name, sample_name + attrs_query = f""" + SELECT {','.join(exp_attr_names)} FROM experiments WHERE exp_id = ? """ cursor = source_conn.cursor() - cursor.execute(names_query, (source_exp_ids[0],)) + cursor.execute(attrs_query, (source_exp_ids[0],)) row = cursor.fetchall()[0] - (source_exp_name, source_sample_name) = (row['name'], row['sample_name']) + exp_attrs = {attr: row[attr] for attr in exp_attr_names} # Massage the target DB file to accomodate the runs # (create new experiment if needed) @@ -70,18 +76,65 @@ def copy_runs_into_db(source_db_path: str, with atomic(target_conn) as target_conn: - load_or_create_experiment(source_exp_name, source_sample_name, - conn=target_conn) + target_exp_id = _create_exp_if_needed(target_conn, + exp_attrs['name'], + exp_attrs['sample_name'], + exp_attrs['format_string'], + exp_attrs['start_time'], + exp_attrs['end_time']) # Finally insert the runs for run_id in run_ids: _copy_single_dataset_into_db(DataSet(run_id=run_id, conn=source_conn), - target_conn) + target_conn, + target_exp_id) + + +def _create_exp_if_needed(target_conn: SomeConnection, + exp_name: str, sample_name: str, + fmt_str: str, + start_time: float, + end_time: Union[float, None]) -> int: + """ + Look up in the database whether an experiment already exists and create + it if it doesn't. Note that experiments do not have GUIDs, so this method + is not guaranteed to work. Matching names and times is the best we can do. + """ + + time_eq = "=" if end_time is not None else "IS" + + exp_exists_query = f""" + SELECT exp_id + FROM experiments + WHERE name = ? + AND sample_name = ? + AND format_string = "{fmt_str}" + AND start_time = ? + AND end_time {time_eq} ? + """ + values = (exp_name, sample_name, start_time, end_time) + cursor = target_conn.execute(exp_exists_query, values) + + rows = cursor.fetchall() + + if len(rows) > 0: + return rows[0]['exp_id'] + else: + create_exp = f""" + INSERT INTO experiments + (name, sample_name, format_string, start_time, end_time) + VALUES + (?,?,?,?,?) + """ + cursor.execute(create_exp, (exp_name, sample_name, fmt_str, + start_time, end_time)) + return cursor.lastrowid def _copy_single_dataset_into_db(dataset: DataSet, - target_conn: SomeConnection) -> None: + target_conn: SomeConnection, + target_exp_id: int) -> None: """ NB: This function should only be called from within :meth:copy_runs_into_db @@ -114,13 +167,11 @@ def _copy_single_dataset_into_db(dataset: DataSet, if len(res) > 0: return - exp_id = get_last_experiment(target_conn) - _copy_runs_table_entries(source_conn, target_conn, dataset.run_id, - exp_id) - _update_run_counter(target_conn, exp_id) + target_exp_id) + _update_run_counter(target_conn, target_exp_id) _copy_layouts_and_dependencies(source_conn, target_conn, dataset.run_id) From 1dc6c445e47c8be9d6f3ecfb73c2716a7d6690ed Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 15:44:14 +0100 Subject: [PATCH 044/719] Extend test to assert experiment equality --- qcodes/tests/dataset/test_database_copy_paste.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index c68e52f03b9..7b4912476c7 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -7,6 +7,7 @@ from qcodes.dataset.database_copy_paste import copy_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_dbs from qcodes.tests.dataset.test_descriptions import some_paramspecs +from qcodes.tests.dataset.test_database_creation_and_upgrading import error_caused_by def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): @@ -23,9 +24,11 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): source_exp = Experiment(conn=source_conn) source_dataset = DataSet(conn=source_conn) - with pytest.raises(ValueError, match='Dataset not completed'): + with pytest.raises(RuntimeError) as excinfo: copy_runs_into_db(source_path, target_path, source_dataset.run_id) + assert error_caused_by(excinfo, 'Dataset not completed') + for ps in some_paramspecs[1].values(): source_dataset.add_parameter(ps) @@ -52,8 +55,8 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): # Now make the interesting comparisons: are the target objects the same as # the source objects? - exp_attrs = ['name', 'sample_name', 'started_at', 'finished_at', - 'format_string'] + exp_attrs = ['name', 'sample_name', 'format_string', 'started_at', + 'finished_at'] ds_attrs = ['name', 'table_name', 'guid', 'number_of_results', 'counter', 'parameters', 'paramspecs', 'exp_name', @@ -62,5 +65,5 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): for ds_attr in ds_attrs: assert getattr(source_dataset, ds_attr) == getattr(target_dataset, ds_attr) - # for exp_attr in exp_attrs: - # assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) + for exp_attr in exp_attrs: + assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) From 084d1f00a481aa3b50ea5f4df1cf6a3b7228a741 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 16:39:11 +0100 Subject: [PATCH 045/719] Change source-target fixture to yield conns --- qcodes/tests/dataset/temporary_databases.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/temporary_databases.py b/qcodes/tests/dataset/temporary_databases.py index e60c6dc997c..19c80a50943 100644 --- a/qcodes/tests/dataset/temporary_databases.py +++ b/qcodes/tests/dataset/temporary_databases.py @@ -26,7 +26,7 @@ def empty_temp_db(): @pytest.fixture(scope='function') -def two_empty_temp_dbs(): +def two_empty_temp_db_connections(): """ Yield the paths of two empty files. Meant for use with the test_database_copy_paste @@ -34,7 +34,13 @@ def two_empty_temp_dbs(): with tempfile.TemporaryDirectory() as tmpdirname: source_path = os.path.join(tmpdirname, 'source.db') target_path = os.path.join(tmpdirname, 'target.db') - yield (source_path, target_path) + source_conn = connect(source_path) + target_conn = connect(target_path) + try: + yield (source_conn, target_conn) + finally: + source_conn.close() + target_conn.close() @pytest.fixture(scope='function') From 8ffc7e3df58c9a146ae371275759714673c7a93d Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 17:00:55 +0100 Subject: [PATCH 046/719] Close connections --- qcodes/dataset/database_copy_paste.py | 35 +++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 22862fd148a..a6fa2caf36f 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -47,6 +47,7 @@ def copy_runs_into_db(source_db_path: str, rows = cursor.fetchall() source_exp_ids = np.unique([exp_id for row in rows for exp_id in row]) if len(source_exp_ids) != 1: + source_conn.close() raise ValueError('Did not receive runs from a single experiment. ' f'Got runs from experiments {source_exp_ids}') @@ -74,21 +75,25 @@ def copy_runs_into_db(source_db_path: str, # this function raises if the target DB file has several experiments # matching both the name and sample_name - with atomic(target_conn) as target_conn: - - target_exp_id = _create_exp_if_needed(target_conn, - exp_attrs['name'], - exp_attrs['sample_name'], - exp_attrs['format_string'], - exp_attrs['start_time'], - exp_attrs['end_time']) - - # Finally insert the runs - for run_id in run_ids: - _copy_single_dataset_into_db(DataSet(run_id=run_id, - conn=source_conn), - target_conn, - target_exp_id) + try: + with atomic(target_conn) as target_conn: + + target_exp_id = _create_exp_if_needed(target_conn, + exp_attrs['name'], + exp_attrs['sample_name'], + exp_attrs['format_string'], + exp_attrs['start_time'], + exp_attrs['end_time']) + + # Finally insert the runs + for run_id in run_ids: + _copy_single_dataset_into_db(DataSet(run_id=run_id, + conn=source_conn), + target_conn, + target_exp_id) + finally: + source_conn.close() + target_conn.close() def _create_exp_if_needed(target_conn: SomeConnection, From 1de9771aa0e8677fdc69d3646c88cca560532247 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 17:01:15 +0100 Subject: [PATCH 047/719] Adapt test to fixture change --- .../tests/dataset/test_database_copy_paste.py | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 7b4912476c7..cab157d8fac 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -4,23 +4,24 @@ from qcodes.dataset.sqlite_base import connect from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import DataSet +from qcodes.dataset.database import path_of_connection from qcodes.dataset.database_copy_paste import copy_runs_into_db -from qcodes.tests.dataset.temporary_databases import two_empty_temp_dbs +from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections from qcodes.tests.dataset.test_descriptions import some_paramspecs from qcodes.tests.dataset.test_database_creation_and_upgrading import error_caused_by -def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): - source_path, target_path = two_empty_temp_dbs +def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_of_connection(source_conn) + target_path = path_of_connection(target_conn) type_casters = {'numeric': float, 'array': (lambda x: np.array(x) if hasattr(x, '__iter__') else np.array([x])), 'text': str} - source_conn = connect(source_path) - target_conn = connect(target_path) - source_exp = Experiment(conn=source_conn) source_dataset = DataSet(conn=source_conn) @@ -32,11 +33,11 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): for ps in some_paramspecs[1].values(): source_dataset.add_parameter(ps) - value = 0 # an arbitrary data value - result = {ps.name: type_casters[ps.type](value) - for ps in some_paramspecs[1].values()} + for value in range(10): + result = {ps.name: type_casters[ps.type](value) + for ps in some_paramspecs[1].values()} + source_dataset.add_result(result) - source_dataset.add_result(result) source_dataset.mark_complete() copy_runs_into_db(source_path, target_path, source_dataset.run_id) @@ -67,3 +68,10 @@ def test_basic_copy_paste(two_empty_temp_dbs, some_paramspecs): for exp_attr in exp_attrs: assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) + + source_data = source_dataset.get_data(*source_dataset.parameters.split(',')) + target_data = target_dataset.get_data(*target_dataset.parameters.split(',')) + + assert source_data == target_data + + From 1a2995d71417e3bb2dda4bd271c66e26e02a020f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 29 Oct 2018 18:11:47 +0100 Subject: [PATCH 048/719] Remove wrong statement in docstring --- qcodes/dataset/database_copy_paste.py | 39 ++++++++++++++++----------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index a6fa2caf36f..c1e1e5239f5 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -88,7 +88,7 @@ def copy_runs_into_db(source_db_path: str, # Finally insert the runs for run_id in run_ids: _copy_single_dataset_into_db(DataSet(run_id=run_id, - conn=source_conn), + conn=source_conn), target_conn, target_exp_id) finally: @@ -128,12 +128,13 @@ def _create_exp_if_needed(target_conn: SomeConnection, else: create_exp = f""" INSERT INTO experiments - (name, sample_name, format_string, start_time, end_time) + (name, sample_name, format_string, + run_counter, start_time, end_time) VALUES - (?,?,?,?,?) + (?,?,?,?,?,?) """ cursor.execute(create_exp, (exp_name, sample_name, fmt_str, - start_time, end_time)) + 0, start_time, end_time)) return cursor.lastrowid @@ -145,14 +146,15 @@ def _copy_single_dataset_into_db(dataset: DataSet, :meth:copy_runs_into_db Insert the given dataset into the specified database file as the latest - run. The database file must exist and its latest experiment must have name - and sample_name matching that of the dataset's parent experiment + run. Trying to insert a run already in the DB is a NOOP. Args: dataset: A dataset representing the run to be copied path_to_db: connection to the DB. Must be atomically guarded + target_exp_id: The exp_id of the (target DB) experiment in which to + insert the run """ if not dataset.completed: @@ -172,23 +174,24 @@ def _copy_single_dataset_into_db(dataset: DataSet, if len(res) > 0: return - _copy_runs_table_entries(source_conn, - target_conn, - dataset.run_id, - target_exp_id) + target_run_id = _copy_runs_table_entries(source_conn, + target_conn, + dataset.run_id, + target_exp_id) _update_run_counter(target_conn, target_exp_id) _copy_layouts_and_dependencies(source_conn, target_conn, dataset.run_id) _copy_results_table(source_conn, target_conn, - dataset.run_id) + dataset.run_id, + target_run_id) def _copy_runs_table_entries(source_conn: SomeConnection, target_conn: SomeConnection, source_run_id: int, - target_exp_id: int) -> None: + target_exp_id: int) -> int: """ Copy an entire runs table row from one DB and paste it all (expect the primary key) into another DB. The two DBs may not be the same. @@ -232,6 +235,8 @@ def _copy_runs_table_entries(source_conn: SomeConnection, cursor = target_conn.cursor() cursor.execute(sql_insert_values, values) + return cursor.lastrowid + def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: """ @@ -313,10 +318,11 @@ def _copy_layouts_and_dependencies(target_conn: SomeConnection, def _copy_results_table(source_conn: SomeConnection, target_conn: SomeConnection, - source_run_id) -> None: + source_run_id: int, + target_run_id: int) -> None: """ Copy the contents of the results table. Creates a new results_table with - a name appropriate for the target DB and updates the + a name appropriate for the target DB and updates the rows of that table """ table_name_query = """ SELECT result_table_name, name @@ -336,7 +342,8 @@ def _copy_results_table(source_conn: SomeConnection, ON runs.exp_id = experiments.exp_id WHERE runs.run_id = ? """ - cursor.execute(format_string_query, (source_run_id,)) + cursor = target_conn.cursor() + cursor.execute(format_string_query, (target_run_id,)) row = cursor.fetchall()[0] format_string = row['format_string'] run_counter = row['run_counter'] @@ -346,7 +353,7 @@ def _copy_results_table(source_conn: SomeConnection, SELECT * FROM "{table_name}" """ - + cursor = source_conn.cursor() cursor.execute(get_data_query) data_rows = cursor.fetchall() data_columns = data_rows[0].keys() From 32194537b23de301809c55c16c520a8acc2b4d7d Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 30 Oct 2018 11:17:10 +0100 Subject: [PATCH 049/719] Add test for experiment routing --- .../tests/dataset/test_database_copy_paste.py | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index cab157d8fac..17ed2dbe4dc 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -1,7 +1,7 @@ import pytest import numpy as np -from qcodes.dataset.sqlite_base import connect +from qcodes.dataset.sqlite_base import connect, get_experiments from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import DataSet from qcodes.dataset.database import path_of_connection @@ -59,7 +59,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): exp_attrs = ['name', 'sample_name', 'format_string', 'started_at', 'finished_at'] - ds_attrs = ['name', 'table_name', 'guid', 'number_of_results', + ds_attrs = ['name', 'guid', 'number_of_results', 'counter', 'parameters', 'paramspecs', 'exp_name', 'sample_name', 'completed', 'snapshot', 'run_timestamp_raw'] @@ -75,3 +75,75 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): assert source_data == target_data +def test_correct_experiment_routing(two_empty_temp_db_connections, + some_paramspecs): + """ + Test that existing experiments are correctly identified AND that multiple + insertions of the same runs don't matter (run insertion is idempotent) + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_exp_1 = Experiment(conn=source_conn) + + # make 5 runs in first experiment + + exp_1_run_ids = [] + for _ in range(5): + + source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id) + exp_1_run_ids.append(source_dataset.run_id) + + for ps in some_paramspecs[2].values(): + source_dataset.add_parameter(ps) + + for val in range(10): + source_dataset.add_result({ps.name: val + for ps in some_paramspecs[2].values()}) + source_dataset.mark_complete() + + # make a new experiment with 1 run + + source_exp_2 = Experiment(conn=source_conn) + ds = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id) + + for ps in some_paramspecs[2].values(): + ds.add_parameter(ps) + + for val in range(10): + ds.add_result({ps.name: val for ps in some_paramspecs[2].values()}) + + ds.mark_complete() + + source_path = path_of_connection(source_conn) + target_path = path_of_connection(target_conn) + + # now copy 2 runs + copy_runs_into_db(source_path, target_path, *exp_1_run_ids[:2]) + + test_exp1 = Experiment(conn=target_conn, exp_id=1) + + assert len(test_exp1) == 2 + + # copy two other runs, one of them already in + copy_runs_into_db(source_path, target_path, *exp_1_run_ids[1:3]) + + assert len(test_exp1) == 3 + + # insert run from different experiment + + copy_runs_into_db(source_path, target_path, ds.run_id) + + assert len(test_exp1) == 3 + + test_exp2 = Experiment(conn=target_conn, exp_id=2) + + assert len(test_exp2) == 1 + + # finally insert every single run from experiment 1 + + copy_runs_into_db(source_path, target_path, *exp_1_run_ids) + + target_exps = get_experiments(target_conn) + + assert len(target_exps) == 2 + assert len(test_exp1) == 5 From fed3b61c2316ebd06e9de5e0dfbd36eee4408b27 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 30 Oct 2018 11:26:45 +0100 Subject: [PATCH 050/719] Change function name --- qcodes/tests/dataset/test_database_copy_paste.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 17ed2dbe4dc..4729b8dbecc 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -4,7 +4,7 @@ from qcodes.dataset.sqlite_base import connect, get_experiments from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import DataSet -from qcodes.dataset.database import path_of_connection +from qcodes.dataset.database import path_to_dbfile from qcodes.dataset.database_copy_paste import copy_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -14,8 +14,8 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): source_conn, target_conn = two_empty_temp_db_connections - source_path = path_of_connection(source_conn) - target_path = path_of_connection(target_conn) + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) type_casters = {'numeric': float, 'array': (lambda x: np.array(x) if hasattr(x, '__iter__') @@ -114,8 +114,8 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, ds.mark_complete() - source_path = path_of_connection(source_conn) - target_path = path_of_connection(target_conn) + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) # now copy 2 runs copy_runs_into_db(source_path, target_path, *exp_1_run_ids[:2]) From ff63bed43408bd9cf8edf9bcf709b40148a2126f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 30 Oct 2018 13:33:11 +0100 Subject: [PATCH 051/719] Pass on connections correctly --- qcodes/dataset/data_set.py | 12 ++++++++---- qcodes/dataset/experiment_container.py | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 7f93402a935..f357ad49e22 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -33,7 +33,7 @@ get_run_timestamp_from_run_id, get_completed_timestamp_from_run_id, update_run_description, - run_exists) + run_exists, SomeConnection) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -848,14 +848,16 @@ def __repr__(self) -> str: # public api -def load_by_id(run_id: int) -> DataSet: +def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: """ Load dataset by run id - Lookup is performed in the database file that is specified in the config. + If no connection is provided, lookup is performed in the database file that + is specified in the config. Args: run_id: run id of the dataset + conn: connection to the database to load from Returns: dataset with the given run id @@ -863,7 +865,9 @@ def load_by_id(run_id: int) -> DataSet: if run_id is None: raise ValueError('run_id has to be a positive integer, not None.') - d = DataSet(path_to_db=get_DB_location(), run_id=run_id) + conn = conn or connect(get_DB_location()) + + d = DataSet(conn=conn, run_id=run_id) return d diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index 08b3653cb3c..a377e830cbb 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -136,7 +136,7 @@ def data_sets(self) -> List[DataSet]: runs = get_runs(self.conn, self.exp_id) data_sets = [] for run in runs: - data_sets.append(load_by_id(run['run_id'])) + data_sets.append(load_by_id(run['run_id'], conn=self.conn)) return data_sets def last_data_set(self) -> DataSet: From ab05e699e7a05d14a45d88aa9ffe97c2af652d7f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 31 Oct 2018 14:35:14 +0100 Subject: [PATCH 052/719] Add method for testing dataset similarity --- qcodes/dataset/data_set.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index f357ad49e22..de8e1f5a849 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -182,6 +182,15 @@ def _clean_up(self) -> None: class DataSet(Sized): + + # the "persistent traits" are the attributes/properties of the DataSet + # that are NOT tied to the representation of the DataSet in any particular + # database + persistent_traits = ('name', 'guid', 'number_of_results', 'counter', + 'parameters', 'paramspecs', 'exp_name', 'sample_name', + 'completed', 'snapshot', 'run_timestamp_raw', + 'description', 'completed_timestamp_raw') + def __init__(self, path_to_db: str=None, run_id: Optional[int]=None, conn=None, @@ -350,6 +359,34 @@ def description(self) -> RunDescriber: def metadata(self) -> Dict: return self._metadata + def the_same_dataset_as(self, other: 'DataSet') -> bool: + """ + Check if two datasets correspond to the same run by comparing + all their persistent traits. Note that this method + does not compare the data itself. + + This function raises if the GUIDs match but anything else doesn't + + Args: + other: the dataset to compare self to + """ + + if not isinstance(other, DataSet): + return False + + guids_match = self.guid == other.guid + + for attr in DataSet.persistent_traits: + if getattr(self, attr) != getattr(other, attr): + if guids_match: + raise RuntimeError('Bad inconsistency detected! ' + 'The two datasets have the same GUID,' + f' but their "{attr}" differ.') + else: + return False + + return True + def run_timestamp(self, fmt: str="%Y-%m-%d %H:%M:%S") -> str: """ Returns run timestamp in a human-readable format From 36a70c97066a5918483ff33c4a6f1204cfe21de1 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 31 Oct 2018 13:42:45 +0100 Subject: [PATCH 053/719] Add a load_by_GUID method to data_set module --- qcodes/dataset/data_set.py | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index de8e1f5a849..fedd198e985 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -884,6 +884,8 @@ def __repr__(self) -> str: return "\n".join(out) +log = logging.getLogger(__name__) + # public api def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: """ @@ -908,6 +910,48 @@ def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: return d +def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: + """ + Load a dataset by its GUID + + If no connection is provided, lookup is performed in the database file that + is specified in the config. + + Args: + guid: guid of the dataset + conn: connection to the database to load from + + Returns: + dataset with the given guid + + Raises: + NameError if no run with the specified GUID exists in the database + RuntimError if several runs with the same GUID are found + """ + conn = conn or connect(get_DB_location()) + + query = """ + SELECT run_id + FROM runs + WHERE guid = ? + """ + cursor = conn.cursor() + cursor.execute(query, (guid,)) + rows = cursor.fetchall() + if len(rows) == 0: + raise NameError(f'No run with guid {guid} found in database.') + elif len(rows) > 1: + errormssg = ('Critical consistency error: multiple runs with' + f' the same GUID found! {len(rows)} runs have GUID ' + f'{guid}') + log.critical(errormssg) + raise RuntimeError(errormssg) + else: + run_id = int(rows[0]['run_id']) + + return DataSet(run_id=run_id, conn=conn) + + def load_by_counter(counter: int, exp_id: int) -> DataSet: """ Load a dataset given its counter in a given experiment From 669cb37e8a36a3d4700bd0f1d68f3551b09381a9 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 31 Oct 2018 14:30:48 +0100 Subject: [PATCH 054/719] Extend tests to check dataset similarity --- .../tests/dataset/test_database_copy_paste.py | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 4729b8dbecc..d532782d2f9 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -3,7 +3,7 @@ from qcodes.dataset.sqlite_base import connect, get_experiments from qcodes.dataset.experiment_container import Experiment -from qcodes.dataset.data_set import DataSet +from qcodes.dataset.data_set import DataSet, load_by_guid from qcodes.dataset.database import path_to_dbfile from qcodes.dataset.database_copy_paste import copy_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections @@ -59,21 +59,16 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): exp_attrs = ['name', 'sample_name', 'format_string', 'started_at', 'finished_at'] - ds_attrs = ['name', 'guid', 'number_of_results', - 'counter', 'parameters', 'paramspecs', 'exp_name', - 'sample_name', 'completed', 'snapshot', 'run_timestamp_raw'] - - for ds_attr in ds_attrs: - assert getattr(source_dataset, ds_attr) == getattr(target_dataset, ds_attr) - - for exp_attr in exp_attrs: - assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) + assert source_dataset.the_same_dataset_as(target_dataset) source_data = source_dataset.get_data(*source_dataset.parameters.split(',')) target_data = target_dataset.get_data(*target_dataset.parameters.split(',')) assert source_data == target_data + for exp_attr in exp_attrs: + assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) + def test_correct_experiment_routing(two_empty_temp_db_connections, some_paramspecs): @@ -105,6 +100,7 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, source_exp_2 = Experiment(conn=source_conn) ds = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id) + exp_2_run_ids = [ds.run_id] for ps in some_paramspecs[2].values(): ds.add_parameter(ps) @@ -147,3 +143,18 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, assert len(target_exps) == 2 assert len(test_exp1) == 5 + + # check that all the datasets match up + for run_id in exp_1_run_ids + exp_2_run_ids: + source_ds = DataSet(conn=source_conn, run_id=run_id) + target_ds = load_by_guid(guid=source_ds.guid, conn=target_conn) + + print(source_ds.paramspecs) + print(target_ds.paramspecs) + + assert source_ds.the_same_dataset_as(target_ds) + + source_data = source_ds.get_data(*source_ds.parameters.split(',')) + target_data = target_ds.get_data(*target_ds.parameters.split(',')) + + assert source_data == target_data From 7db1467b5be8c91ea33264c3797e14a9604baa30 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 31 Oct 2018 14:31:35 +0100 Subject: [PATCH 055/719] Handle data column types correctly --- qcodes/dataset/database_copy_paste.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index c1e1e5239f5..596cc3a2173 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -174,6 +174,9 @@ def _copy_single_dataset_into_db(dataset: DataSet, if len(res) > 0: return + parspecs = dataset.paramspecs.values() + data_column_names_and_types = ",".join([p.sql_repr() for p in parspecs]) + target_run_id = _copy_runs_table_entries(source_conn, target_conn, dataset.run_id, @@ -185,7 +188,8 @@ def _copy_single_dataset_into_db(dataset: DataSet, _copy_results_table(source_conn, target_conn, dataset.run_id, - target_run_id) + target_run_id, + data_column_names_and_types) def _copy_runs_table_entries(source_conn: SomeConnection, @@ -251,8 +255,8 @@ def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: cursor.execute(update_sql, (target_exp_id,)) -def _copy_layouts_and_dependencies(target_conn: SomeConnection, - source_conn: SomeConnection, +def _copy_layouts_and_dependencies(source_conn: SomeConnection, + target_conn: SomeConnection, source_run_id: int) -> None: """ Copy over the layouts and dependencies tables. Note that the layout_ids @@ -261,7 +265,7 @@ def _copy_layouts_and_dependencies(target_conn: SomeConnection, layout_id 2 that depends on layout_id 1) """ layout_query = """ - SELECT layout_id, run_id, parameter, label, unit, inferred_from + SELECT layout_id, run_id, "parameter", label, unit, inferred_from FROM layouts WHERE run_id = ? """ @@ -319,7 +323,8 @@ def _copy_layouts_and_dependencies(target_conn: SomeConnection, def _copy_results_table(source_conn: SomeConnection, target_conn: SomeConnection, source_run_id: int, - target_run_id: int) -> None: + target_run_id: int, + column_names_and_types: str) -> None: """ Copy the contents of the results table. Creates a new results_table with a name appropriate for the target DB and updates the rows of that table @@ -364,11 +369,10 @@ def _copy_results_table(source_conn: SomeConnection, exp_id, run_counter) - column_names = ','.join(data_columns) make_table = f""" CREATE TABLE "{target_table_name}" ( id INTEGER PRIMARY KEY, - {column_names} + {column_names_and_types} ) """ @@ -378,6 +382,7 @@ def _copy_results_table(source_conn: SomeConnection, # according to one of our reports, multiple single-row inserts # are okay if there's only one commit + column_names = ','.join(data_columns) value_placeholders = sql_placeholder_string(len(data_columns)) insert_data = f""" INSERT INTO "{target_table_name}" From 8de6a8a87eb49d3c86e0a6c1ea1f68449db5982b Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 5 Nov 2018 09:59:49 +0100 Subject: [PATCH 056/719] Improve two docstrings --- qcodes/dataset/database_copy_paste.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 596cc3a2173..e2ffb2d5205 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -14,7 +14,8 @@ def sql_placeholder_string(n: int) -> str: """ - Return an SQL placeholder string of length n. + Return an SQL value placeholder string of length n. + Example: sql_placeholder_string(5) returns '(?,?,?,?,?)' """ return '(' + ','.join('?'*n) + ')' @@ -29,7 +30,8 @@ def copy_runs_into_db(source_db_path: str, Args: source_db_path: Path to the source DB file - target_db_path: Path to the target DB file + target_db_path: Path to the target DB file. The target DB file will be + created if it does not exist. run_ids: The run_ids of the runs to copy into the target DB file """ From 9add02b6f3ee6ac7edec3db383affc3536684c32 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 10:51:55 +0100 Subject: [PATCH 057/719] Move log initiation line --- qcodes/dataset/data_set.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index fedd198e985..76f57bf2bff 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -42,6 +42,8 @@ from qcodes.utils.deprecate import deprecate import qcodes.config +log = logging.getLogger(__name__) + # TODO: as of now every time a result is inserted with add_result the db is # saved same for add_results. IS THIS THE BEHAVIOUR WE WANT? @@ -884,8 +886,6 @@ def __repr__(self) -> str: return "\n".join(out) -log = logging.getLogger(__name__) - # public api def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: """ From 95c2b49f446b8e708a8e887dda2f84c57379c07e Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 10:52:37 +0100 Subject: [PATCH 058/719] Fix typo --- qcodes/dataset/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 76f57bf2bff..feb1952c675 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -926,7 +926,7 @@ def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: Raises: NameError if no run with the specified GUID exists in the database - RuntimError if several runs with the same GUID are found + RuntimeError if several runs with the same GUID are found """ conn = conn or connect(get_DB_location()) From f9a4285727191ad5c7cf36afe3e53694700dfa52 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 11:16:37 +0100 Subject: [PATCH 059/719] Refactor run_id from guid into sqlite_base --- qcodes/dataset/data_set.py | 28 +++++++--------------- qcodes/dataset/database_copy_paste.py | 13 ++++------ qcodes/dataset/sqlite_base.py | 34 ++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index feb1952c675..eff84f2c623 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -30,6 +30,7 @@ get_experiment_name_from_experiment_id, get_sample_name_from_experiment_id, get_guid_from_run_id, + get_runid_from_guid, get_run_timestamp_from_run_id, get_completed_timestamp_from_run_id, update_run_description, @@ -925,29 +926,16 @@ def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: dataset with the given guid Raises: - NameError if no run with the specified GUID exists in the database - RuntimeError if several runs with the same GUID are found + NameError if no run with the given GUID exists in the database + RuntimeError if several runs with the given GUID are found """ conn = conn or connect(get_DB_location()) - query = """ - SELECT run_id - FROM runs - WHERE guid = ? - """ - cursor = conn.cursor() - cursor.execute(query, (guid,)) - rows = cursor.fetchall() - if len(rows) == 0: - raise NameError(f'No run with guid {guid} found in database.') - elif len(rows) > 1: - errormssg = ('Critical consistency error: multiple runs with' - f' the same GUID found! {len(rows)} runs have GUID ' - f'{guid}') - log.critical(errormssg) - raise RuntimeError(errormssg) - else: - run_id = int(rows[0]['run_id']) + # this function raises a RuntimeError if more than one run matches the GUID + run_id = get_runid_from_guid(conn, guid) + + if run_id is None: + raise NameError(f'No run with GUID: {guid} found in database.') return DataSet(run_id=run_id, conn=conn) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index e2ffb2d5205..66517deafa8 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -8,6 +8,7 @@ connect, format_table_name, get_last_experiment, + get_runid_from_guid, insert_column, SomeConnection) @@ -165,15 +166,9 @@ def _copy_single_dataset_into_db(dataset: DataSet, source_conn = dataset.conn - already_in_query = """ - SELECT run_id - FROM runs - WHERE guid = ? - """ - cursor = target_conn.cursor() - cursor.execute(already_in_query, (dataset.guid,)) - res = cursor.fetchall() - if len(res) > 0: + run_id = get_runid_from_guid(target_conn, dataset.guid) + + if run_id is not None: return parspecs = dataset.paramspecs.values() diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 3b2930ea399..c3b8f665d64 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1008,7 +1008,6 @@ def modify_values(conn: SomeConnection, c = atomic_transaction(conn, query, *values) return c.rowcount - def modify_many_values(conn: SomeConnection, formatted_name: str, start_index: int, @@ -1205,6 +1204,39 @@ def get_setpoints(conn: SomeConnection, return output +def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: + """ + Get the run_id of a run based on the guid + + Args: + conn: connection to the database + guid: the guid to look up + + Raises: + RunTimeError if more than one run with the given GUID exists + """ + query = """ + SELECT run_id + FROM runs + WHERE guid = ? + """ + cursor = conn.cursor() + cursor.execute(query, (guid,)) + rows = cursor.fetchall() + if len(rows) == 0: + run_id = None + elif len(rows) > 1: + errormssg = ('Critical consistency error: multiple runs with' + f' the same GUID found! {len(rows)} runs have GUID ' + f'{guid}') + log.critical(errormssg) + raise RuntimeError(errormssg) + else: + run_id = int(rows[0]['run_id']) + + return run_id + + def get_layout(conn: SomeConnection, layout_id) -> Dict[str, str]: """ From d51455c098ecc8f4283422f23b0632b445fec73e Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 11:25:44 +0100 Subject: [PATCH 060/719] Be correct about conn and path_to_db in docstring --- qcodes/dataset/experiment_container.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index a377e830cbb..b5baa5d1156 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -33,7 +33,9 @@ def __init__(self, path_to_db: Optional[str]=None, created. If exp_id is not None, an experiment is loaded. Args: - path_to_db: The path of the database file to create in/load from + path_to_db: The path of the database file to create in/load from. + If a conn is passed together with path_to_db, an exception is + raised exp_id: The id of the experiment to load name: The name of the experiment to create. Ignored if exp_id is not None @@ -41,9 +43,16 @@ def __init__(self, path_to_db: Optional[str]=None, is not None format_string: The format string used to name result-tables. Ignored if exp_id is not None. - conn: connection to the database. If not supplied, a new connection + conn: connection to the database. If not supplied, the constructor + first tries to use path_to_db to figure out where to connect to. + If path_to_db is not supplied either, a new connection to the DB file specified in the config is made """ + + if path_to_db is not None and conn is not None: + raise ValueError('Received BOTH conn and path_to_db. Please ' + 'provide only one or the other.') + self._path_to_db = path_to_db or get_DB_location() self.conn = conn or connect(self.path_to_db, get_DB_debug()) From 41feda85e1fe5eb2dde699ce02464cd65250e0af Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 11:32:06 +0100 Subject: [PATCH 061/719] Move list definition closer to where it is used --- qcodes/tests/dataset/test_database_copy_paste.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index d532782d2f9..f7e26c8dfcc 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -56,9 +56,6 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): # Now make the interesting comparisons: are the target objects the same as # the source objects? - exp_attrs = ['name', 'sample_name', 'format_string', 'started_at', - 'finished_at'] - assert source_dataset.the_same_dataset_as(target_dataset) source_data = source_dataset.get_data(*source_dataset.parameters.split(',')) @@ -66,6 +63,9 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): assert source_data == target_data + exp_attrs = ['name', 'sample_name', 'format_string', 'started_at', + 'finished_at'] + for exp_attr in exp_attrs: assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) From 69130ef9e3999e50fce4f2282489e4f8dbdf90ad Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 13:22:33 +0100 Subject: [PATCH 062/719] Check harder for idempotency of run insertion --- .../tests/dataset/test_database_copy_paste.py | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index f7e26c8dfcc..475bd02f832 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -1,3 +1,6 @@ +from os.path import getmtime +from contextlib import contextmanager + import pytest import numpy as np @@ -11,6 +14,21 @@ from qcodes.tests.dataset.test_database_creation_and_upgrading import error_caused_by +@contextmanager +def raise_if_file_changed(path_to_file: str): + """ + Context manager that raises if a file is modified. + On Windows, the OS modification time resolution is 100 ns + """ + pre_operation_time = getmtime(path_to_file) + # we don't want to catch and re-raise anything, since there is no clean-up + # that we need to perform. Hence no try-except here + yield + post_operation_time = getmtime(path_to_file) + if pre_operation_time != post_operation_time: + raise RuntimeError(f'File {path_to_file} was modified.') + + def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): source_conn, target_conn = two_empty_temp_db_connections @@ -47,7 +65,8 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): length1 = len(target_exp) # trying to insert the same run again should be a NOOP - copy_runs_into_db(source_path, target_path, source_dataset.run_id) + with raise_if_file_changed(target_path): + copy_runs_into_db(source_path, target_path, source_dataset.run_id) assert len(target_exp) == length1 @@ -69,6 +88,10 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): for exp_attr in exp_attrs: assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr) + # trying to insert the same run again should be a NOOP + with raise_if_file_changed(target_path): + copy_runs_into_db(source_path, target_path, source_dataset.run_id) + def test_correct_experiment_routing(two_empty_temp_db_connections, some_paramspecs): @@ -126,7 +149,6 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, assert len(test_exp1) == 3 # insert run from different experiment - copy_runs_into_db(source_path, target_path, ds.run_id) assert len(test_exp1) == 3 @@ -139,6 +161,11 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, copy_runs_into_db(source_path, target_path, *exp_1_run_ids) + # check for idempotency once more by inserting all the runs but in another + # order + with raise_if_file_changed(target_path): + copy_runs_into_db(source_path, target_path, *exp_1_run_ids[::-1]) + target_exps = get_experiments(target_conn) assert len(target_exps) == 2 From 35872619a9003dae438ef30c966981caeecdb5be Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 13:26:54 +0100 Subject: [PATCH 063/719] Rename some variables and add an assert --- qcodes/tests/dataset/test_database_copy_paste.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 475bd02f832..7fef790571f 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -139,23 +139,23 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, # now copy 2 runs copy_runs_into_db(source_path, target_path, *exp_1_run_ids[:2]) - test_exp1 = Experiment(conn=target_conn, exp_id=1) + target_exp1 = Experiment(conn=target_conn, exp_id=1) - assert len(test_exp1) == 2 + assert len(target_exp1) == 2 # copy two other runs, one of them already in copy_runs_into_db(source_path, target_path, *exp_1_run_ids[1:3]) - assert len(test_exp1) == 3 + assert len(target_exp1) == 3 # insert run from different experiment copy_runs_into_db(source_path, target_path, ds.run_id) - assert len(test_exp1) == 3 + assert len(target_exp1) == 3 - test_exp2 = Experiment(conn=target_conn, exp_id=2) + target_exp2 = Experiment(conn=target_conn, exp_id=2) - assert len(test_exp2) == 1 + assert len(target_exp2) == 1 # finally insert every single run from experiment 1 @@ -169,7 +169,8 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, target_exps = get_experiments(target_conn) assert len(target_exps) == 2 - assert len(test_exp1) == 5 + assert len(target_exp1) == 5 + assert len(target_exp2) == 1 # check that all the datasets match up for run_id in exp_1_run_ids + exp_2_run_ids: From 4e42110bd51e7259cd22b0b285dd871ce5cdcd5f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 13:27:47 +0100 Subject: [PATCH 064/719] Remove print calls --- qcodes/tests/dataset/test_database_copy_paste.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 7fef790571f..be539b46738 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -177,9 +177,6 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, source_ds = DataSet(conn=source_conn, run_id=run_id) target_ds = load_by_guid(guid=source_ds.guid, conn=target_conn) - print(source_ds.paramspecs) - print(target_ds.paramspecs) - assert source_ds.the_same_dataset_as(target_ds) source_data = source_ds.get_data(*source_ds.parameters.split(',')) From 0484d96a884f4f703a9bdce8357207db7f025bd0 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 13:42:28 +0100 Subject: [PATCH 065/719] Add test for load_by_guid --- qcodes/tests/dataset/test_dataset_loading.py | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_dataset_loading.py b/qcodes/tests/dataset/test_dataset_loading.py index 43a6b955a47..30ecaf5c866 100644 --- a/qcodes/tests/dataset/test_dataset_loading.py +++ b/qcodes/tests/dataset/test_dataset_loading.py @@ -3,13 +3,19 @@ import pytest -from qcodes.dataset.data_set import (new_data_set, load_by_id, load_by_counter, +from qcodes.dataset.data_set import (DataSet, + new_data_set, + load_by_guid, + load_by_id, + load_by_counter, ParamSpec) from qcodes.dataset.data_export import get_data_by_id from qcodes.dataset.experiment_container import new_experiment # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) +# pylint: disable=unused-import +from qcodes.tests.dataset.test_descriptions import some_paramspecs @pytest.mark.usefixtures("experiment") @@ -178,3 +184,16 @@ def test_get_data_by_id_order(dataset): data_dict = {el['name']: el['data'] for el in data[1]} assert data_dict['indep1'] == 1 assert data_dict['indep2'] == 2 + + +@pytest.mark.usefixtures('experiment') +def test_load_by_guid(some_paramspecs): + paramspecs = some_paramspecs[2] + ds = DataSet() + ds.add_parameter(paramspecs['ps1']) + ds.add_parameter(paramspecs['ps2']) + ds.add_result({'ps1': 1, 'ps2': 2}) + + loaded_ds = load_by_guid(ds.guid) + + assert loaded_ds.the_same_dataset_as(ds) From 338966957ec8a231d684087570bd80c339d21ec2 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 14:51:55 +0100 Subject: [PATCH 066/719] Add mini-test for the_same_dataset_as --- qcodes/tests/dataset/test_dataset_basic.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index e0dbcfd830b..050f98ade27 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -556,3 +556,17 @@ def test_metadata(): with pytest.raises(ValueError, match=match): for tag, value in sorry_metadata.items(): ds1.add_metadata(tag, value) + + +def test_the_same_dataset_as(some_paramspecs): + paramspecs = some_paramspecs[2] + ds = DataSet() + ds.add_parameter(paramspecs['ps1']) + ds.add_parameter(paramspecs['ps2']) + ds.add_result({'ps1': 1, 'ps2': 2}) + + same_ds_from_load = DataSet(run_id=ds.run_id) + assert ds.the_same_dataset_as(same_ds_from_load) + + new_ds = DataSet() + assert not ds.the_same_dataset_as(new_ds) From 7005584b16ced6c4ede8daf57005fc1c7789ac88 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 15:16:06 +0100 Subject: [PATCH 067/719] Test that runs from different experiments raise --- .../tests/dataset/test_database_copy_paste.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index be539b46738..cc7b2c10876 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -183,3 +183,58 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, target_data = target_ds.get_data(*target_ds.parameters.split(',')) assert source_data == target_data + + +def test_runs_from_different_experiments_raises(two_empty_temp_db_connections, + some_paramspecs): + """ + Test that inserting runs from multiple experiments raises + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + source_exp_1 = Experiment(conn=source_conn) + source_exp_2 = Experiment(conn=source_conn) + + # make 5 runs in first experiment + + exp_1_run_ids = [] + for _ in range(5): + + source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id) + exp_1_run_ids.append(source_dataset.run_id) + + for ps in some_paramspecs[2].values(): + source_dataset.add_parameter(ps) + + for val in range(10): + source_dataset.add_result({ps.name: val + for ps in some_paramspecs[2].values()}) + source_dataset.mark_complete() + + # make 5 runs in second experiment + + exp_2_run_ids = [] + for _ in range(5): + + source_dataset = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id) + exp_2_run_ids.append(source_dataset.run_id) + + for ps in some_paramspecs[2].values(): + source_dataset.add_parameter(ps) + + for val in range(10): + source_dataset.add_result({ps.name: val + for ps in some_paramspecs[2].values()}) + source_dataset.mark_complete() + + run_ids = exp_1_run_ids + exp_2_run_ids + source_exp_ids = np.unique([1, 2]) + matchstring = ('Did not receive runs from a single experiment\\. ' + f'Got runs from experiments {source_exp_ids}') + # make the matchstring safe to use as a regexp + matchstring = matchstring.replace('[', '\\[').replace(']', '\\]') + with pytest.raises(ValueError, match=matchstring): + copy_runs_into_db(source_path, target_path, *run_ids) From 14619bdcef40b4bca0239bc4fb347964cc608da9 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 16:25:20 +0100 Subject: [PATCH 068/719] Add newline --- qcodes/dataset/database_copy_paste.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 66517deafa8..094c9eb5314 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -100,7 +100,8 @@ def copy_runs_into_db(source_db_path: str, def _create_exp_if_needed(target_conn: SomeConnection, - exp_name: str, sample_name: str, + exp_name: str, + sample_name: str, fmt_str: str, start_time: float, end_time: Union[float, None]) -> int: From 894357fbb706a3686ecca7bd4f1582d1d75da7b3 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 16:37:28 +0100 Subject: [PATCH 069/719] Warn if multiple possible target experiments exist --- qcodes/dataset/database_copy_paste.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 094c9eb5314..7d51efbdbbe 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -1,4 +1,5 @@ from typing import Union +from warnings import warn import numpy as np @@ -127,6 +128,13 @@ def _create_exp_if_needed(target_conn: SomeConnection, rows = cursor.fetchall() + if len(rows) > 1: + + exp_id = rows[0]['exp_id'] + warn(f'{len(rows)} experiments found in target DB that match name, ' + 'sample_name, fmt_str, start_time, and end_time. ' + f'Inserting into the experiment with exp_id={exp_id}.') + return exp_id if len(rows) > 0: return rows[0]['exp_id'] else: From af6f188daca6c6925deea3629f72d38d0b78eee4 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 16:45:18 +0100 Subject: [PATCH 070/719] Fix typo --- qcodes/dataset/database_copy_paste.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 7d51efbdbbe..9989536c800 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -164,7 +164,7 @@ def _copy_single_dataset_into_db(dataset: DataSet, Args: dataset: A dataset representing the run to be copied - path_to_db: connection to the DB. Must be atomically guarded + target_conn: connection to the DB. Must be atomically guarded target_exp_id: The exp_id of the (target DB) experiment in which to insert the run """ From a2b9fc3570d9437a846851e23ac17dd1ffee343f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 8 Nov 2018 16:45:38 +0100 Subject: [PATCH 071/719] Assert full reason for raise --- qcodes/tests/dataset/test_database_copy_paste.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index cc7b2c10876..274fa5d9fc8 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -46,7 +46,8 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): with pytest.raises(RuntimeError) as excinfo: copy_runs_into_db(source_path, target_path, source_dataset.run_id) - assert error_caused_by(excinfo, 'Dataset not completed') + assert error_caused_by(excinfo, ('Dataset not completed. An incomplete ' + 'dataset can not be copied.')) for ps in some_paramspecs[1].values(): source_dataset.add_parameter(ps) From db222caed4ef11f34ea9ae2241f0008c618544aa Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 12:48:34 +0100 Subject: [PATCH 072/719] Change "bad" -> "critical" --- qcodes/dataset/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index eff84f2c623..0a4e0c530ed 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -382,7 +382,7 @@ def the_same_dataset_as(self, other: 'DataSet') -> bool: for attr in DataSet.persistent_traits: if getattr(self, attr) != getattr(other, attr): if guids_match: - raise RuntimeError('Bad inconsistency detected! ' + raise RuntimeError('Critical inconsistency detected! ' 'The two datasets have the same GUID,' f' but their "{attr}" differ.') else: From b89e557a851bdae2450c773f903c5ed53cb8f9bc Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 12:55:21 +0100 Subject: [PATCH 073/719] Add test for copying empty run --- .../tests/dataset/test_database_copy_paste.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 274fa5d9fc8..2f30f980745 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -239,3 +239,26 @@ def test_runs_from_different_experiments_raises(two_empty_temp_db_connections, matchstring = matchstring.replace('[', '\\[').replace(']', '\\]') with pytest.raises(ValueError, match=matchstring): copy_runs_into_db(source_path, target_path, *run_ids) + + +def test_extracting_dataless_run(two_empty_temp_db_connections, + some_paramspecs): + """ + Although contrived, it could happen that a run with no data is extracted + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + Experiment(conn=source_conn) + + source_ds = DataSet(conn=source_conn) + + source_ds.mark_complete() + + copy_runs_into_db(source_path, target_path, source_ds.run_id) + + loaded_ds = DataSet(conn=target_conn, run_id=1) + + assert loaded_ds.the_same_dataset_as(source_ds) From 1527e4cccf1d3b80b0c6153464024d27a99a198e Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 13:16:09 +0100 Subject: [PATCH 074/719] Make empty dataset extractable --- qcodes/dataset/database_copy_paste.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 9989536c800..336eb08104a 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -367,20 +367,30 @@ def _copy_results_table(source_conn: SomeConnection, cursor = source_conn.cursor() cursor.execute(get_data_query) data_rows = cursor.fetchall() - data_columns = data_rows[0].keys() - data_columns.remove('id') + if len(data_rows) > 0: + data_columns = data_rows[0].keys() + data_columns.remove('id') + else: + data_columns = [] target_table_name = format_table_name(format_string, run_name, exp_id, run_counter) - make_table = f""" - CREATE TABLE "{target_table_name}" ( - id INTEGER PRIMARY KEY, - {column_names_and_types} - ) - """ + if column_names_and_types != '': + make_table = f""" + CREATE TABLE "{target_table_name}" ( + id INTEGER PRIMARY KEY, + {column_names_and_types} + ) + """ + else: + make_table = f""" + CREATE TABLE "{target_table_name}" ( + id INTEGER PRIMARY KEY + ) + """ cursor = target_conn.cursor() cursor.execute(make_table) From 8b933238c9a8431e9338a966f9189db3dd8a10be Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 13:01:50 +0100 Subject: [PATCH 075/719] Fix typo --- qcodes/dataset/sqlite_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index c3b8f665d64..8828d011364 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1024,7 +1024,7 @@ def modify_many_values(conn: SomeConnection, len_requested = start_index + len(list_of_values[0]) available = _len - start_index if len_requested > _len: - reason = f""""Modify operation Out of bounds. + reason = f"""Modify operation Out of bounds. Trying to modify {len(list_of_values)} results, but therere are only {available} results. """ @@ -1213,7 +1213,7 @@ def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: guid: the guid to look up Raises: - RunTimeError if more than one run with the given GUID exists + RuntimeError if more than one run with the given GUID exists """ query = """ SELECT run_id From 9c8a4767eec3ded804e5d2f419ebef53426f0205 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 13:38:38 +0100 Subject: [PATCH 076/719] Add test for correct result table names --- .../tests/dataset/test_database_copy_paste.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 2f30f980745..88f95917334 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -262,3 +262,43 @@ def test_extracting_dataless_run(two_empty_temp_db_connections, loaded_ds = DataSet(conn=target_conn, run_id=1) assert loaded_ds.the_same_dataset_as(source_ds) + + +def test_result_table_naming(two_empty_temp_db_connections, + some_paramspecs): + """ + Does this raise? + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + source_exp1 = Experiment(conn=source_conn) + source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_1_1.add_parameter(ps) + source_ds_1_1.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_1_1.mark_complete() + + source_exp2 = Experiment(conn=source_conn) + source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_2_1.add_parameter(ps) + source_ds_2_1.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_2_1.mark_complete() + source_ds_2_2 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_2_2.add_parameter(ps) + source_ds_2_2.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_2_2.mark_complete() + + copy_runs_into_db(source_path, target_path, source_ds_2_2.run_id) + + # The target ds ought to have a runs table "results-1-1" + target_ds = DataSet(conn=target_conn, run_id=1) + + assert target_ds.table_name == "results-1-1" From 56f1abb98209d5b9fefe76bb7f577084fcdf5548 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 13:49:31 +0100 Subject: [PATCH 077/719] Sprinkle custom dataset names in test --- qcodes/tests/dataset/test_database_copy_paste.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_copy_paste.py index 88f95917334..8556b152e4a 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_copy_paste.py @@ -41,7 +41,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): 'text': str} source_exp = Experiment(conn=source_conn) - source_dataset = DataSet(conn=source_conn) + source_dataset = DataSet(conn=source_conn, name="basic_copy_paste_name") with pytest.raises(RuntimeError) as excinfo: copy_runs_into_db(source_path, target_path, source_dataset.run_id) @@ -123,7 +123,7 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, # make a new experiment with 1 run source_exp_2 = Experiment(conn=source_conn) - ds = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id) + ds = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id, name="lala") exp_2_run_ids = [ds.run_id] for ps in some_paramspecs[2].values(): @@ -289,7 +289,9 @@ def test_result_table_naming(two_empty_temp_db_connections, source_ds_2_1.add_result({ps.name: 0.0 for ps in some_paramspecs[2].values()}) source_ds_2_1.mark_complete() - source_ds_2_2 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id) + source_ds_2_2 = DataSet(conn=source_conn, + exp_id=source_exp2.exp_id, + name="customname") for ps in some_paramspecs[2].values(): source_ds_2_2.add_parameter(ps) source_ds_2_2.add_result({ps.name: 0.0 @@ -298,7 +300,7 @@ def test_result_table_naming(two_empty_temp_db_connections, copy_runs_into_db(source_path, target_path, source_ds_2_2.run_id) - # The target ds ought to have a runs table "results-1-1" + # The target ds ought to have a runs table "customname-1-1" target_ds = DataSet(conn=target_conn, run_id=1) - assert target_ds.table_name == "results-1-1" + assert target_ds.table_name == "customname-1-1" From 6fa904ad0ee696954da85433827d4fb5567e5f89 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 13:52:42 +0100 Subject: [PATCH 078/719] Ensure correct results table name --- qcodes/dataset/database_copy_paste.py | 29 +++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 336eb08104a..4407d4c9776 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -191,11 +191,12 @@ def _copy_single_dataset_into_db(dataset: DataSet, _copy_layouts_and_dependencies(source_conn, target_conn, dataset.run_id) - _copy_results_table(source_conn, - target_conn, - dataset.run_id, - target_run_id, - data_column_names_and_types) + target_table_name = _copy_results_table(source_conn, + target_conn, + dataset.run_id, + target_run_id, + data_column_names_and_types) + _update_result_table_name(target_conn, target_table_name, target_run_id) def _copy_runs_table_entries(source_conn: SomeConnection, @@ -330,10 +331,12 @@ def _copy_results_table(source_conn: SomeConnection, target_conn: SomeConnection, source_run_id: int, target_run_id: int, - column_names_and_types: str) -> None: + column_names_and_types: str) -> str: """ Copy the contents of the results table. Creates a new results_table with a name appropriate for the target DB and updates the rows of that table + + Returns the name of the new results table """ table_name_query = """ SELECT result_table_name, name @@ -409,3 +412,17 @@ def _copy_results_table(source_conn: SomeConnection, for row in data_rows: # the first row entry is the ID, which is automatically inserted cursor.execute(insert_data, tuple(v for v in row[1:])) + + return target_table_name + + +def _update_result_table_name(target_conn: SomeConnection, + target_table_name: str, + target_run_id: int) -> None: + sql = """ + UPDATE runs + SET result_table_name = ? + WHERE run_id = ? + """ + cursor = target_conn.cursor() + cursor.execute(sql, (target_table_name, target_run_id)) From 5a1aefb85d80f92bc2391dc9219a557b2a167ecd Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Fri, 9 Nov 2018 14:01:18 +0100 Subject: [PATCH 079/719] Use run_id = -1 instead of None for missing runs --- qcodes/dataset/data_set.py | 2 +- qcodes/dataset/database_copy_paste.py | 2 +- qcodes/dataset/sqlite_base.py | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 0a4e0c530ed..0e7a22284a9 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -934,7 +934,7 @@ def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: # this function raises a RuntimeError if more than one run matches the GUID run_id = get_runid_from_guid(conn, guid) - if run_id is None: + if run_id == -1: raise NameError(f'No run with GUID: {guid} found in database.') return DataSet(run_id=run_id, conn=conn) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_copy_paste.py index 4407d4c9776..f7d220a5521 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_copy_paste.py @@ -177,7 +177,7 @@ def _copy_single_dataset_into_db(dataset: DataSet, run_id = get_runid_from_guid(target_conn, dataset.guid) - if run_id is not None: + if run_id != -1: return parspecs = dataset.paramspecs.values() diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 8828d011364..cc062d25933 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1212,6 +1212,9 @@ def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: conn: connection to the database guid: the guid to look up + Returns: + The run_id if found, else -1. + Raises: RuntimeError if more than one run with the given GUID exists """ @@ -1224,7 +1227,7 @@ def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: cursor.execute(query, (guid,)) rows = cursor.fetchall() if len(rows) == 0: - run_id = None + run_id = -1 elif len(rows) > 1: errormssg = ('Critical consistency error: multiple runs with' f' the same GUID found! {len(rows)} runs have GUID ' @@ -1322,6 +1325,7 @@ def get_dependencies(conn: SomeConnection, res = many_many(c, 'independent', 'axis_num') return res + # Higher level Wrappers From fbfa07de7cbe17c42a0ff901f460983f1a242234 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 10:06:12 +0100 Subject: [PATCH 080/719] Rename from copy-paste to extract --- ...copy_paste.py => database_extract_runs.py} | 28 +++++++++---------- ...paste.py => test_database_extract_runs.py} | 28 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) rename qcodes/dataset/{database_copy_paste.py => database_extract_runs.py} (95%) rename qcodes/tests/dataset/{test_database_copy_paste.py => test_database_extract_runs.py} (90%) diff --git a/qcodes/dataset/database_copy_paste.py b/qcodes/dataset/database_extract_runs.py similarity index 95% rename from qcodes/dataset/database_copy_paste.py rename to qcodes/dataset/database_extract_runs.py index f7d220a5521..65287e1c82d 100644 --- a/qcodes/dataset/database_copy_paste.py +++ b/qcodes/dataset/database_extract_runs.py @@ -22,13 +22,13 @@ def sql_placeholder_string(n: int) -> str: return '(' + ','.join('?'*n) + ')' -def copy_runs_into_db(source_db_path: str, - target_db_path: str, *run_ids) -> None: +def extract_runs_into_db(source_db_path: str, + target_db_path: str, *run_ids) -> None: """ - Copy a selection of runs into another DB file. All runs must come from the - same experiment. They will be added to an experiment with the same name - and sample_name in the target db. If such an experiment does not exist, - it will be created. + Extract a selection of runs into another DB file. All runs must come from + the same experiment. They will be added to an experiment with the same name + and sample_name in the target db. If such an experiment does not exist, it + will be created. Args: source_db_path: Path to the source DB file @@ -91,10 +91,10 @@ def copy_runs_into_db(source_db_path: str, # Finally insert the runs for run_id in run_ids: - _copy_single_dataset_into_db(DataSet(run_id=run_id, - conn=source_conn), - target_conn, - target_exp_id) + _extract_single_dataset_into_db(DataSet(run_id=run_id, + conn=source_conn), + target_conn, + target_exp_id) finally: source_conn.close() target_conn.close() @@ -150,12 +150,12 @@ def _create_exp_if_needed(target_conn: SomeConnection, return cursor.lastrowid -def _copy_single_dataset_into_db(dataset: DataSet, - target_conn: SomeConnection, - target_exp_id: int) -> None: +def _extract_single_dataset_into_db(dataset: DataSet, + target_conn: SomeConnection, + target_exp_id: int) -> None: """ NB: This function should only be called from within - :meth:copy_runs_into_db + :meth:extract_runs_into_db Insert the given dataset into the specified database file as the latest run. diff --git a/qcodes/tests/dataset/test_database_copy_paste.py b/qcodes/tests/dataset/test_database_extract_runs.py similarity index 90% rename from qcodes/tests/dataset/test_database_copy_paste.py rename to qcodes/tests/dataset/test_database_extract_runs.py index 8556b152e4a..19c4115a5f8 100644 --- a/qcodes/tests/dataset/test_database_copy_paste.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -8,7 +8,7 @@ from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import DataSet, load_by_guid from qcodes.dataset.database import path_to_dbfile -from qcodes.dataset.database_copy_paste import copy_runs_into_db +from qcodes.dataset.database_extract_runs import extract_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections from qcodes.tests.dataset.test_descriptions import some_paramspecs from qcodes.tests.dataset.test_database_creation_and_upgrading import error_caused_by @@ -29,7 +29,7 @@ def raise_if_file_changed(path_to_file: str): raise RuntimeError(f'File {path_to_file} was modified.') -def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): +def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): source_conn, target_conn = two_empty_temp_db_connections source_path = path_to_dbfile(source_conn) @@ -44,7 +44,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): source_dataset = DataSet(conn=source_conn, name="basic_copy_paste_name") with pytest.raises(RuntimeError) as excinfo: - copy_runs_into_db(source_path, target_path, source_dataset.run_id) + extract_runs_into_db(source_path, target_path, source_dataset.run_id) assert error_caused_by(excinfo, ('Dataset not completed. An incomplete ' 'dataset can not be copied.')) @@ -59,7 +59,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): source_dataset.mark_complete() - copy_runs_into_db(source_path, target_path, source_dataset.run_id) + extract_runs_into_db(source_path, target_path, source_dataset.run_id) target_exp = Experiment(conn=target_conn, exp_id=1) @@ -67,7 +67,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): # trying to insert the same run again should be a NOOP with raise_if_file_changed(target_path): - copy_runs_into_db(source_path, target_path, source_dataset.run_id) + extract_runs_into_db(source_path, target_path, source_dataset.run_id) assert len(target_exp) == length1 @@ -91,7 +91,7 @@ def test_basic_copy_paste(two_empty_temp_db_connections, some_paramspecs): # trying to insert the same run again should be a NOOP with raise_if_file_changed(target_path): - copy_runs_into_db(source_path, target_path, source_dataset.run_id) + extract_runs_into_db(source_path, target_path, source_dataset.run_id) def test_correct_experiment_routing(two_empty_temp_db_connections, @@ -138,19 +138,19 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, target_path = path_to_dbfile(target_conn) # now copy 2 runs - copy_runs_into_db(source_path, target_path, *exp_1_run_ids[:2]) + extract_runs_into_db(source_path, target_path, *exp_1_run_ids[:2]) target_exp1 = Experiment(conn=target_conn, exp_id=1) assert len(target_exp1) == 2 # copy two other runs, one of them already in - copy_runs_into_db(source_path, target_path, *exp_1_run_ids[1:3]) + extract_runs_into_db(source_path, target_path, *exp_1_run_ids[1:3]) assert len(target_exp1) == 3 # insert run from different experiment - copy_runs_into_db(source_path, target_path, ds.run_id) + extract_runs_into_db(source_path, target_path, ds.run_id) assert len(target_exp1) == 3 @@ -160,12 +160,12 @@ def test_correct_experiment_routing(two_empty_temp_db_connections, # finally insert every single run from experiment 1 - copy_runs_into_db(source_path, target_path, *exp_1_run_ids) + extract_runs_into_db(source_path, target_path, *exp_1_run_ids) # check for idempotency once more by inserting all the runs but in another # order with raise_if_file_changed(target_path): - copy_runs_into_db(source_path, target_path, *exp_1_run_ids[::-1]) + extract_runs_into_db(source_path, target_path, *exp_1_run_ids[::-1]) target_exps = get_experiments(target_conn) @@ -238,7 +238,7 @@ def test_runs_from_different_experiments_raises(two_empty_temp_db_connections, # make the matchstring safe to use as a regexp matchstring = matchstring.replace('[', '\\[').replace(']', '\\]') with pytest.raises(ValueError, match=matchstring): - copy_runs_into_db(source_path, target_path, *run_ids) + extract_runs_into_db(source_path, target_path, *run_ids) def test_extracting_dataless_run(two_empty_temp_db_connections, @@ -257,7 +257,7 @@ def test_extracting_dataless_run(two_empty_temp_db_connections, source_ds.mark_complete() - copy_runs_into_db(source_path, target_path, source_ds.run_id) + extract_runs_into_db(source_path, target_path, source_ds.run_id) loaded_ds = DataSet(conn=target_conn, run_id=1) @@ -298,7 +298,7 @@ def test_result_table_naming(two_empty_temp_db_connections, for ps in some_paramspecs[2].values()}) source_ds_2_2.mark_complete() - copy_runs_into_db(source_path, target_path, source_ds_2_2.run_id) + extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id) # The target ds ought to have a runs table "customname-1-1" target_ds = DataSet(conn=target_conn, run_id=1) From 9f08566aef1c2a6179db37ed5c0b043676bca1b6 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 10:17:10 +0100 Subject: [PATCH 081/719] Move sql_placeholder_string to sqlite_base --- qcodes/dataset/database_extract_runs.py | 11 ++--------- qcodes/dataset/sqlite_base.py | 8 ++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 65287e1c82d..b603b45a9ad 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -11,15 +11,8 @@ get_last_experiment, get_runid_from_guid, insert_column, - SomeConnection) - - -def sql_placeholder_string(n: int) -> str: - """ - Return an SQL value placeholder string of length n. - Example: sql_placeholder_string(5) returns '(?,?,?,?,?)' - """ - return '(' + ','.join('?'*n) + ')' + SomeConnection, + sql_placeholder_string) def extract_runs_into_db(source_db_path: str, diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index cc062d25933..229bfafc214 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -108,6 +108,14 @@ "run_description"] +def sql_placeholder_string(n: int) -> str: + """ + Return an SQL value placeholder string for n values. + Example: sql_placeholder_string(5) returns '(?,?,?,?,?)' + """ + return '(' + ','.join('?'*n) + ')' + + class ConnectionPlus(wrapt.ObjectProxy): """ A class to extend the sqlite3.Connection object with a single extra From 15ce049f56d612c35833ca2de5f2cea11de380ba Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 10:34:38 +0100 Subject: [PATCH 082/719] Refactor get_exp_ids_from_run_ids into sqlite_base --- qcodes/dataset/database_extract_runs.py | 13 ++----------- qcodes/dataset/sqlite_base.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index b603b45a9ad..89ba6140ab4 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -8,6 +8,7 @@ from qcodes.dataset.sqlite_base import (atomic, connect, format_table_name, + get_exp_ids_from_run_ids, get_last_experiment, get_runid_from_guid, insert_column, @@ -31,18 +32,8 @@ def extract_runs_into_db(source_db_path: str, """ # Validate that all runs are from the same experiment - - sql_placeholders = sql_placeholder_string(len(run_ids)) - exp_id_query = f""" - SELECT exp_id - FROM runs - WHERE run_id IN {sql_placeholders} - """ source_conn = connect(source_db_path) - cursor = source_conn.cursor() - cursor.execute(exp_id_query, run_ids) - rows = cursor.fetchall() - source_exp_ids = np.unique([exp_id for row in rows for exp_id in row]) + source_exp_ids = np.unique(get_exp_ids_from_run_ids(source_conn, run_ids)) if len(source_exp_ids) != 1: source_conn.close() raise ValueError('Did not receive runs from a single experiment. ' diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 229bfafc214..2f118926d54 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1471,6 +1471,31 @@ def get_experiments(conn: SomeConnection) -> List[sqlite3.Row]: return c.fetchall() +def get_exp_ids_from_run_ids(conn: SomeConnection, + run_ids: Sequence[int]) -> List[int]: + """ + Get the corresponding exp_id for a sequence of run_ids + + Args: + conn: connection to the database + run_ids: a sequence of the run_ids to get the exp_id of + + Returns: + A list of exp_ids matching the run_ids + """ + sql_placeholders = sql_placeholder_string(len(run_ids)) + exp_id_query = f""" + SELECT exp_id + FROM runs + WHERE run_id IN {sql_placeholders} + """ + cursor = conn.cursor() + cursor.execute(exp_id_query, run_ids) + rows = cursor.fetchall() + + return [exp_id for row in rows for exp_id in row] + + def get_last_experiment(conn: SomeConnection) -> Optional[int]: """ Return last started experiment id From b38931a0d6b32593e5c2b8898e2b9b3a6b3f3bb4 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 12:40:13 +0100 Subject: [PATCH 083/719] Add input validation of run_ids --- qcodes/dataset/database_extract_runs.py | 14 ++++++- qcodes/dataset/sqlite_base.py | 30 ++++++++++++++ .../dataset/test_database_extract_runs.py | 39 +++++++++++++++++++ qcodes/tests/dataset/test_sqlite_base.py | 23 +++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 89ba6140ab4..6e4514a330c 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -12,6 +12,7 @@ get_last_experiment, get_runid_from_guid, insert_column, + is_run_id_in_database, SomeConnection, sql_placeholder_string) @@ -30,9 +31,20 @@ def extract_runs_into_db(source_db_path: str, created if it does not exist. run_ids: The run_ids of the runs to copy into the target DB file """ + source_conn = connect(source_db_path) + + # Validate that all runs are in the source database + do_runs_exist = is_run_id_in_database(source_conn, run_ids) + if False in do_runs_exist.values(): + source_conn.close() + non_existing_ids = [rid for rid in run_ids if not do_runs_exist[rid]] + err_mssg = ("Error: not all run_ids exist in the source database. " + "The following run(s) is/are not present: " + f"{non_existing_ids}") + raise ValueError(err_mssg) # Validate that all runs are from the same experiment - source_conn = connect(source_db_path) + source_exp_ids = np.unique(get_exp_ids_from_run_ids(source_conn, run_ids)) if len(source_exp_ids) != 1: source_conn.close() diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2f118926d54..34ab8a3ee4c 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -792,6 +792,36 @@ def init_db(conn: SomeConnection)->None: transaction(conn, _dependencies_table_schema) +def is_run_id_in_database(conn: SomeConnection, + *run_ids: int) -> Dict[int, bool]: + """ + Look up run_ids and return a dictionary with the answers to the question + "is this run_id in the database?" + + Args: + conn: the connection to the database + run_ids: the run_ids to look up + + Returns: + a dict with the run_ids as keys and bools as values. True means that + the run_id DOES exist in the database + """ + run_ids = np.unique(run_ids) + placeholders = sql_placeholder_string(len(run_ids)) + + query = f""" + SELECT run_id + FROM runs + WHERE run_id in {placeholders} + """ + + cursor = conn.cursor() + cursor.execute(query, run_ids) + rows = cursor.fetchall() + existing_ids = [row[0] for row in rows] + return {run_id: (run_id in existing_ids) for run_id in run_ids} + + def is_column_in_table(conn: SomeConnection, table: str, column: str) -> bool: """ A look-before-you-leap function to look up if a table has a certain column. diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 19c4115a5f8..b370ec63a8c 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -1,5 +1,6 @@ from os.path import getmtime from contextlib import contextmanager +import re import pytest import numpy as np @@ -29,6 +30,44 @@ def raise_if_file_changed(path_to_file: str): raise RuntimeError(f'File {path_to_file} was modified.') +def test_missing_runs_raises(two_empty_temp_db_connections, some_paramspecs): + """ + Test that an error is raised if runs not present in the source DB are + attempted extracted + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_exp_1 = Experiment(conn=source_conn) + + # make 5 runs in first experiment + + exp_1_run_ids = [] + for _ in range(5): + + source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id) + exp_1_run_ids.append(source_dataset.run_id) + + for ps in some_paramspecs[2].values(): + source_dataset.add_parameter(ps) + + for val in range(10): + source_dataset.add_result({ps.name: val + for ps in some_paramspecs[2].values()}) + source_dataset.mark_complete() + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + run_ids = [1, 8, 5, 3, 2, 4, 4, 4, 7, 8] + wrong_ids = [8, 7, 8] + + expected_err = ("Error: not all run_ids exist in the source database. " + "The following run(s) is/are not present: " + f"{wrong_ids}") + + with pytest.raises(ValueError, match=re.escape(expected_err)): + extract_runs_into_db(source_path, target_path, *run_ids) + def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): source_conn, target_conn = two_empty_temp_db_connections diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index fc309304aac..60499421f2f 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -9,12 +9,14 @@ import hypothesis.strategies as hst from hypothesis import given import unicodedata +import numpy as np from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies import qcodes.dataset.sqlite_base as mut # mut: module under test from qcodes.dataset.database import get_DB_location, path_to_dbfile from qcodes.dataset.guids import generate_guid +from qcodes.dataset.data_set import DataSet from qcodes.dataset.param_spec import ParamSpec # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import \ @@ -185,3 +187,24 @@ def test_runs_table_columns(empty_temp_db): colnames.remove(row['name']) assert colnames == [] + + +def test_is_run_id_in_db(empty_temp_db): + conn = mut.connect(get_DB_location()) + mut.new_experiment(conn, 'test_exp', 'no_sample') + + for _ in range(5): + ds = DataSet(conn=conn, run_id=None) + print(ds.run_id) + + # there should now be run_ids 1, 2, 3, 4, 5 in the database + good_ids = [1, 2, 3, 4, 5] + try_ids = [1, 3, 9999, 23, 0, 1, 1, 3, 34] + + sorted_try_ids = np.unique(try_ids) + + expected_dict = {tid: (tid in good_ids) for tid in sorted_try_ids} + + acquired_dict = mut.is_run_id_in_database(conn, *try_ids) + + assert expected_dict == acquired_dict From 81caec62a42809ee0ae14c65cb5bca5ee590b500 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 13:03:06 +0100 Subject: [PATCH 084/719] Refactor exp trait lookup into sqlite_base --- qcodes/dataset/database_extract_runs.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 6e4514a330c..185cde29f30 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -13,12 +13,13 @@ get_runid_from_guid, insert_column, is_run_id_in_database, + select_many_where, SomeConnection, sql_placeholder_string) def extract_runs_into_db(source_db_path: str, - target_db_path: str, *run_ids) -> None: + target_db_path: str, *run_ids: int) -> None: """ Extract a selection of runs into another DB file. All runs must come from the same experiment. They will be added to an experiment with the same name @@ -57,15 +58,13 @@ def extract_runs_into_db(source_db_path: str, exp_attr_names = ['name', 'sample_name', 'start_time', 'end_time', 'format_string'] - attrs_query = f""" - SELECT {','.join(exp_attr_names)} - FROM experiments - WHERE exp_id = ? - """ - cursor = source_conn.cursor() - cursor.execute(attrs_query, (source_exp_ids[0],)) - row = cursor.fetchall()[0] - exp_attrs = {attr: row[attr] for attr in exp_attr_names} + exp_attr_vals = select_many_where(source_conn, + 'experiments', + *exp_attr_names, + where_column='exp_id', + where_value=source_exp_ids[0]) + + exp_attrs = dict(zip(exp_attr_names, exp_attr_vals)) # Massage the target DB file to accomodate the runs # (create new experiment if needed) From 25bc49ae751ec032c77c6dabe3afb3f3a28c42db Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 14:09:24 +0100 Subject: [PATCH 085/719] Refactor finding matching exps into sqlite_base --- qcodes/dataset/database_extract_runs.py | 35 +++++++++------------- qcodes/dataset/sqlite_base.py | 40 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 185cde29f30..4f98d71dddc 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -10,6 +10,7 @@ format_table_name, get_exp_ids_from_run_ids, get_last_experiment, + get_matching_exp_ids, get_runid_from_guid, insert_column, is_run_id_in_database, @@ -107,31 +108,22 @@ def _create_exp_if_needed(target_conn: SomeConnection, is not guaranteed to work. Matching names and times is the best we can do. """ - time_eq = "=" if end_time is not None else "IS" + matching_exp_ids = get_matching_exp_ids(target_conn, + name=exp_name, + sample_name=sample_name, + format_string=fmt_str, + start_time=start_time, + end_time=end_time) - exp_exists_query = f""" - SELECT exp_id - FROM experiments - WHERE name = ? - AND sample_name = ? - AND format_string = "{fmt_str}" - AND start_time = ? - AND end_time {time_eq} ? - """ - values = (exp_name, sample_name, start_time, end_time) - cursor = target_conn.execute(exp_exists_query, values) - - rows = cursor.fetchall() - - if len(rows) > 1: + if len(matching_exp_ids) > 1: - exp_id = rows[0]['exp_id'] - warn(f'{len(rows)} experiments found in target DB that match name, ' - 'sample_name, fmt_str, start_time, and end_time. ' + exp_id = matching_exp_ids[0] + warn(f'{len(matching_exp_ids)} experiments found in target DB that ' + 'match name, sample_name, fmt_str, start_time, and end_time. ' f'Inserting into the experiment with exp_id={exp_id}.') return exp_id - if len(rows) > 0: - return rows[0]['exp_id'] + if len(matching_exp_ids) == 1: + return matching_exp_ids[0] else: create_exp = f""" INSERT INTO experiments @@ -140,6 +132,7 @@ def _create_exp_if_needed(target_conn: SomeConnection, VALUES (?,?,?,?,?,?) """ + cursor = target_conn.cursor() cursor.execute(create_exp, (exp_name, sample_name, fmt_str, 0, start_time, end_time)) return cursor.lastrowid diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 34ab8a3ee4c..be7cccf6e98 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1501,6 +1501,46 @@ def get_experiments(conn: SomeConnection) -> List[sqlite3.Row]: return c.fetchall() +def get_matching_exp_ids(conn: SomeConnection, **match_conditions) -> List: + """ + Get exp_ids for experiments matching the match_conditions + + Raises: + ValueError if a match_condition that is not "name", "sample_name", + "format_string", "run_counter", "start_time", or "end_time" + """ + valid_conditions = ["name", "sample_name", "start_time", "end_time", + "run_counter", "format_string"] + + for mcond in match_conditions: + if mcond not in valid_conditions: + raise ValueError(f"{mcond} is not a valid match condition.") + + end_time = match_conditions.get('end_time', None) + time_eq = "=" if end_time is not None else "IS" + + query = "SELECT exp_id FROM experiments " + for n, mcond in enumerate(match_conditions): + if n == 0: + query += f"WHERE {mcond} = ? " + else: + query += f"AND {mcond} = ? " + + # now some syntax clean-up + if "format_string" in match_conditions: + format_string = match_conditions["format_string"] + query = query.replace("format_string = ?", + f'format_string = "{format_string}"') + match_conditions.pop("format_string") + query = query.replace("end_time = ?", f"end_time {time_eq} ?") + + cursor = conn.cursor() + cursor.execute(query, tuple(match_conditions.values())) + rows = cursor.fetchall() + + return [row[0] for row in rows] + + def get_exp_ids_from_run_ids(conn: SomeConnection, run_ids: Sequence[int]) -> List[int]: """ From 8d82c163d8e6aa22f61e7feac8f088ed0914b313 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 14:16:32 +0100 Subject: [PATCH 086/719] Extend a test to load by run_id --- qcodes/tests/dataset/test_database_extract_runs.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index b370ec63a8c..f111a39baa6 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -68,6 +68,7 @@ def test_missing_runs_raises(two_empty_temp_db_connections, some_paramspecs): with pytest.raises(ValueError, match=re.escape(expected_err)): extract_runs_into_db(source_path, target_path, *run_ids) + def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): source_conn, target_conn = two_empty_temp_db_connections @@ -303,10 +304,11 @@ def test_extracting_dataless_run(two_empty_temp_db_connections, assert loaded_ds.the_same_dataset_as(source_ds) -def test_result_table_naming(two_empty_temp_db_connections, - some_paramspecs): +def test_result_table_naming_and_run_id(two_empty_temp_db_connections, + some_paramspecs): """ - Does this raise? + Check that a correct result table name is given and that a correct run_id + is assigned """ source_conn, target_conn = two_empty_temp_db_connections @@ -340,6 +342,9 @@ def test_result_table_naming(two_empty_temp_db_connections, extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id) # The target ds ought to have a runs table "customname-1-1" + # and ough to be the same dataset as its "ancestor" target_ds = DataSet(conn=target_conn, run_id=1) assert target_ds.table_name == "customname-1-1" + assert target_ds.the_same_dataset_as(source_ds_2_2) + From 5ade9166e85b555b9cb19d0d34aa2422b94dbf6a Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 14:25:17 +0100 Subject: [PATCH 087/719] Apply fix for load by run_id test failure --- qcodes/dataset/database_extract_runs.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 4f98d71dddc..4528bf33974 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -116,7 +116,6 @@ def _create_exp_if_needed(target_conn: SomeConnection, end_time=end_time) if len(matching_exp_ids) > 1: - exp_id = matching_exp_ids[0] warn(f'{len(matching_exp_ids)} experiments found in target DB that ' 'match name, sample_name, fmt_str, start_time, and end_time. ' @@ -178,7 +177,8 @@ def _extract_single_dataset_into_db(dataset: DataSet, _update_run_counter(target_conn, target_exp_id) _copy_layouts_and_dependencies(source_conn, target_conn, - dataset.run_id) + dataset.run_id, + target_run_id) target_table_name = _copy_results_table(source_conn, target_conn, dataset.run_id, @@ -252,7 +252,8 @@ def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: def _copy_layouts_and_dependencies(source_conn: SomeConnection, target_conn: SomeConnection, - source_run_id: int) -> None: + source_run_id: int, + target_run_id: int) -> None: """ Copy over the layouts and dependencies tables. Note that the layout_ids are not preserved in the target DB, but of course their relationships are @@ -279,7 +280,8 @@ def _copy_layouts_and_dependencies(source_conn: SomeConnection, source_layout_ids = [] target_layout_ids = [] for row in rows: - values = tuple(row[colname] for colname in colnames) + values = ((target_run_id,) + + tuple(row[colname] for colname in colnames[1:])) cursor.execute(layout_insert, values) source_layout_ids.append(row['layout_id']) target_layout_ids.append(cursor.lastrowid) From a73c133c9a8f8a89e359e7519985f71e9f4788e8 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 14:36:00 +0100 Subject: [PATCH 088/719] Refactor new exp creation into sqlite_base --- qcodes/dataset/database_extract_runs.py | 19 +++++++-------- qcodes/dataset/sqlite_base.py | 32 +++++++++++++++++-------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 4528bf33974..1147857bc92 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -14,6 +14,7 @@ get_runid_from_guid, insert_column, is_run_id_in_database, + new_experiment, select_many_where, SomeConnection, sql_placeholder_string) @@ -124,17 +125,13 @@ def _create_exp_if_needed(target_conn: SomeConnection, if len(matching_exp_ids) == 1: return matching_exp_ids[0] else: - create_exp = f""" - INSERT INTO experiments - (name, sample_name, format_string, - run_counter, start_time, end_time) - VALUES - (?,?,?,?,?,?) - """ - cursor = target_conn.cursor() - cursor.execute(create_exp, (exp_name, sample_name, fmt_str, - 0, start_time, end_time)) - return cursor.lastrowid + lastrowid = new_experiment(target_conn, + name=exp_name, + sample_name=sample_name, + format_string=fmt_str, + start_time=start_time, + end_time=end_time) + return lastrowid def _extract_single_dataset_into_db(dataset: DataSet, diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index be7cccf6e98..0fd27591d5d 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1370,27 +1370,39 @@ def get_dependencies(conn: SomeConnection, def new_experiment(conn: SomeConnection, name: str, sample_name: str, - format_string: Optional[str] = "{}-{}-{}" + format_string: Optional[str]="{}-{}-{}", + start_time: Optional[float]=None, + end_time: Optional[float]=None, ) -> int: - """ Add new experiment to container + """ + Add new experiment to container. Args: conn: database connection name: the name of the experiment sample_name: the name of the current sample format_string: basic format string for table-name - must contain 3 placeholders. + must contain 3 placeholders. + start_time: time when the experiment was started. Do not supply this + unless you have a very good reason to do so. + end_time: time when the experiment was completed. Do not supply this + unless you have a VERY good reason to do so + Returns: id: row-id of the created experiment """ query = """ - INSERT INTO experiments - (name, sample_name, start_time, format_string, run_counter) - VALUES - (?,?,?,?,?) - """ - curr = atomic_transaction(conn, query, name, sample_name, - time.time(), format_string, 0) + INSERT INTO experiments + (name, sample_name, format_string, + run_counter, start_time, end_time) + VALUES + (?,?,?,?,?,?) + """ + + start_time = start_time or time.time() + values = (name, sample_name, format_string, 0, start_time, end_time) + + curr = atomic_transaction(conn, query, *values) return curr.lastrowid From 2c10e5fd315c0733de415bca197f4ff2d3d3dbc8 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 15:20:01 +0100 Subject: [PATCH 089/719] Remove a type annotation --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 0fd27591d5d..3ff0142e1c5 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -793,7 +793,7 @@ def init_db(conn: SomeConnection)->None: def is_run_id_in_database(conn: SomeConnection, - *run_ids: int) -> Dict[int, bool]: + *run_ids) -> Dict[int, bool]: """ Look up run_ids and return a dictionary with the answers to the question "is this run_id in the database?" From 986f51709277d5130f91e3b288f40eb907f33fed Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Mon, 12 Nov 2018 15:36:01 +0100 Subject: [PATCH 090/719] Add test for different load methods --- .../dataset/test_database_extract_runs.py | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index f111a39baa6..a61f1995da1 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -7,7 +7,8 @@ from qcodes.dataset.sqlite_base import connect, get_experiments from qcodes.dataset.experiment_container import Experiment -from qcodes.dataset.data_set import DataSet, load_by_guid +from qcodes.dataset.data_set import (DataSet, load_by_guid, load_by_counter, + load_by_id) from qcodes.dataset.database import path_to_dbfile from qcodes.dataset.database_extract_runs import extract_runs_into_db from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections @@ -348,3 +349,48 @@ def test_result_table_naming_and_run_id(two_empty_temp_db_connections, assert target_ds.table_name == "customname-1-1" assert target_ds.the_same_dataset_as(source_ds_2_2) + +def test_load_by_X_functions(two_empty_temp_db_connections, + some_paramspecs): + """ + Test some different loading functions + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + source_exp1 = Experiment(conn=source_conn) + source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_1_1.add_parameter(ps) + source_ds_1_1.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_1_1.mark_complete() + + source_exp2 = Experiment(conn=source_conn) + source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_2_1.add_parameter(ps) + source_ds_2_1.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_2_1.mark_complete() + source_ds_2_2 = DataSet(conn=source_conn, + exp_id=source_exp2.exp_id, + name="customname") + for ps in some_paramspecs[2].values(): + source_ds_2_2.add_parameter(ps) + source_ds_2_2.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds_2_2.mark_complete() + + extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id) + + test_ds = load_by_guid(source_ds_2_2.guid, target_conn) + assert source_ds_2_2.the_same_dataset_as(test_ds) + + test_ds = load_by_id(1, target_conn) + assert source_ds_2_2.the_same_dataset_as(test_ds) + + test_ds = load_by_counter(1, 1, target_conn) + assert source_ds_2_2.the_same_dataset_as(test_ds) From 3e4ab8322d1cb060a57beb6fd99507946f6fcfac Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 13 Nov 2018 10:50:18 +0100 Subject: [PATCH 091/719] Remove "counter" from persistent dataset traits --- qcodes/dataset/data_set.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 0e7a22284a9..18fad27da4b 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -189,7 +189,7 @@ class DataSet(Sized): # the "persistent traits" are the attributes/properties of the DataSet # that are NOT tied to the representation of the DataSet in any particular # database - persistent_traits = ('name', 'guid', 'number_of_results', 'counter', + persistent_traits = ('name', 'guid', 'number_of_results', 'parameters', 'paramspecs', 'exp_name', 'sample_name', 'completed', 'snapshot', 'run_timestamp_raw', 'description', 'completed_timestamp_raw') @@ -940,7 +940,8 @@ def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: return DataSet(run_id=run_id, conn=conn) -def load_by_counter(counter: int, exp_id: int) -> DataSet: +def load_by_counter(counter: int, exp_id: int, + conn: Optional[SomeConnection]=None) -> DataSet: """ Load a dataset given its counter in a given experiment @@ -949,11 +950,13 @@ def load_by_counter(counter: int, exp_id: int) -> DataSet: Args: counter: counter of the dataset within the given experiment exp_id: id of the experiment where to look for the dataset + conn: connection to the database to load from. If not provided, a + connection to the DB file specified in the config is made Returns: dataset of the given counter in the given experiment """ - conn = connect(get_DB_location()) + conn = conn or connect(get_DB_location()) sql = """ SELECT run_id FROM From 92b268f84eeedf62275aaa86da88f8e46fcc9f27 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 13 Nov 2018 10:52:19 +0100 Subject: [PATCH 092/719] Refactor runs extractor to use create_run from sqlite_base --- qcodes/dataset/database_extract_runs.py | 285 +++++------------------- 1 file changed, 54 insertions(+), 231 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 1147857bc92..865585915b8 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -7,6 +7,7 @@ from qcodes.dataset.experiment_container import load_or_create_experiment from qcodes.dataset.sqlite_base import (atomic, connect, + create_run, format_table_name, get_exp_ids_from_run_ids, get_last_experiment, @@ -14,6 +15,7 @@ get_runid_from_guid, insert_column, is_run_id_in_database, + mark_run_complete, new_experiment, select_many_where, SomeConnection, @@ -165,251 +167,72 @@ def _extract_single_dataset_into_db(dataset: DataSet, return parspecs = dataset.paramspecs.values() - data_column_names_and_types = ",".join([p.sql_repr() for p in parspecs]) - - target_run_id = _copy_runs_table_entries(source_conn, - target_conn, - dataset.run_id, - target_exp_id) - _update_run_counter(target_conn, target_exp_id) - _copy_layouts_and_dependencies(source_conn, - target_conn, - dataset.run_id, - target_run_id) - target_table_name = _copy_results_table(source_conn, - target_conn, - dataset.run_id, - target_run_id, - data_column_names_and_types) - _update_result_table_name(target_conn, target_table_name, target_run_id) - - -def _copy_runs_table_entries(source_conn: SomeConnection, - target_conn: SomeConnection, - source_run_id: int, - target_exp_id: int) -> int: - """ - Copy an entire runs table row from one DB and paste it all - (expect the primary key) into another DB. The two DBs may not be the same. - Note that this function does not create a new results table - - This function should be executed with an atomically guarded target_conn - as a part of a larger atomic transaction - """ - runs_row_query = """ - SELECT * - FROM runs - WHERE run_id = ? - """ - cursor = source_conn.cursor() - cursor.execute(runs_row_query, (source_run_id,)) - source_runs_row = cursor.fetchall()[0] - source_colnames = set(source_runs_row.keys()) - - # There might not be any runs in the target DB, hence we ask PRAGMA - cursor = target_conn.cursor() - cursor.execute("PRAGMA table_info(runs)", ()) - tab_info = cursor.fetchall() - target_colnames = set([r['name'] for r in tab_info]) - - for colname in source_colnames.difference(target_colnames): - insert_column(target_conn, 'runs', colname) - - # the first entry is "run_id" - sql_colnames = str(tuple(source_runs_row.keys()[1:])).replace("'", "") - sql_placeholders = sql_placeholder_string(len(source_runs_row.keys())-1) - - sql_insert_values = f""" - INSERT INTO runs - {sql_colnames} - VALUES - {sql_placeholders} - """ - # the first two entries in source_runs_row are run_id and exp_id - values = tuple([target_exp_id] + [val for val in source_runs_row[2:]]) - cursor = target_conn.cursor() - cursor.execute(sql_insert_values, values) + #metadata = dataset.get_metadata() - return cursor.lastrowid + _, target_run_id, target_table_name = create_run(target_conn, + target_exp_id, + name=dataset.name, + guid=dataset.guid, + parameters=list(parspecs)) + _populate_results_table(source_conn, + target_conn, + dataset.table_name, + target_table_name) + mark_run_complete(target_conn, target_run_id) + _rewrite_timestamps(target_conn, + target_run_id, + dataset.run_timestamp_raw, + dataset.completed_timestamp_raw) -def _update_run_counter(target_conn: SomeConnection, target_exp_id) -> None: - """ - Update the run_counter in the target DB experiments table - """ - update_sql = """ - UPDATE experiments - SET run_counter = run_counter + 1 - WHERE exp_id = ? - """ - cursor = target_conn.cursor() - cursor.execute(update_sql, (target_exp_id,)) -def _copy_layouts_and_dependencies(source_conn: SomeConnection, - target_conn: SomeConnection, - source_run_id: int, - target_run_id: int) -> None: +def _populate_results_table(source_conn: SomeConnection, + target_conn: SomeConnection, + source_table_name: str, + target_table_name: str) -> None: """ - Copy over the layouts and dependencies tables. Note that the layout_ids - are not preserved in the target DB, but of course their relationships are - (e.g. layout_id 10 that depends on layout_id 9 might be inserted as - layout_id 2 that depends on layout_id 1) + Copy over all the entries of the results table """ - layout_query = """ - SELECT layout_id, run_id, "parameter", label, unit, inferred_from - FROM layouts - WHERE run_id = ? - """ - cursor = source_conn.cursor() - cursor.execute(layout_query, (source_run_id,)) - rows = cursor.fetchall() - - layout_insert = """ - INSERT INTO layouts - (run_id, parameter, label, unit, inferred_from) - VALUES (?,?,?,?,?) - """ - - colnames = ('run_id', 'parameter', 'label', 'unit', 'inferred_from') - cursor = target_conn.cursor() - source_layout_ids = [] - target_layout_ids = [] - for row in rows: - values = ((target_run_id,) + - tuple(row[colname] for colname in colnames[1:])) - cursor.execute(layout_insert, values) - source_layout_ids.append(row['layout_id']) - target_layout_ids.append(cursor.lastrowid) - - # for the dependencies, we need a map from source layout_id to - # target layout_id - layout_id_map = dict(zip(source_layout_ids, target_layout_ids)) - - placeholders = sql_placeholder_string(len(source_layout_ids)) - - deps_query = f""" - SELECT dependent, independent, axis_num - FROM dependencies - WHERE dependent IN {placeholders} - OR independent IN {placeholders} - """ - - cursor = source_conn.cursor() - cursor.execute(deps_query, tuple(source_layout_ids*2)) - rows = cursor.fetchall() - - deps_insert = """ - INSERT INTO dependencies - (dependent, independent, axis_num) - VALUES (?,?,?) - """ - cursor = target_conn.cursor() + get_data_query = f""" + SELECT * + FROM "{source_table_name}" + """ - for row in rows: - values = (layout_id_map[row['dependent']], - layout_id_map[row['independent']], - row['axis_num']) - cursor.execute(deps_insert, values) + source_cursor = source_conn.cursor() + target_cursor = target_conn.cursor() + for row in source_cursor.execute(get_data_query): + column_names = ','.join(row.keys()[1:]) # the first key is "id" + values = tuple(val for val in row[1:]) + value_placeholders = sql_placeholder_string(len(values)) + insert_data_query = f""" + INSERT INTO "{target_table_name}" + ({column_names}) + values {value_placeholders} + """ + target_cursor.execute(insert_data_query, values) -def _copy_results_table(source_conn: SomeConnection, - target_conn: SomeConnection, - source_run_id: int, - target_run_id: int, - column_names_and_types: str) -> str: - """ - Copy the contents of the results table. Creates a new results_table with - a name appropriate for the target DB and updates the rows of that table - Returns the name of the new results table +def _rewrite_timestamps(target_conn: SomeConnection, target_run_id: int, + correct_run_timestamp: float, + correct_completed_timestamp: float) -> None: + """ + Update the timestamp to match the original one """ - table_name_query = """ - SELECT result_table_name, name - FROM runs - WHERE run_id = ? - """ - cursor = source_conn.cursor() - cursor.execute(table_name_query, (source_run_id,)) - row = cursor.fetchall()[0] - table_name = row['result_table_name'] - run_name = row['name'] - - format_string_query = """ - SELECT format_string, run_counter, experiments.exp_id - FROM experiments - INNER JOIN runs - ON runs.exp_id = experiments.exp_id - WHERE runs.run_id = ? - """ + query = """ + UPDATE runs + SET run_timestamp = ? + WHERE run_id = ? + """ cursor = target_conn.cursor() - cursor.execute(format_string_query, (target_run_id,)) - row = cursor.fetchall()[0] - format_string = row['format_string'] - run_counter = row['run_counter'] - exp_id = int(row['exp_id']) + cursor.execute(query, (correct_run_timestamp, target_run_id)) - get_data_query = f""" - SELECT * - FROM "{table_name}" - """ - cursor = source_conn.cursor() - cursor.execute(get_data_query) - data_rows = cursor.fetchall() - if len(data_rows) > 0: - data_columns = data_rows[0].keys() - data_columns.remove('id') - else: - data_columns = [] - - target_table_name = format_table_name(format_string, - run_name, - exp_id, - run_counter) - - if column_names_and_types != '': - make_table = f""" - CREATE TABLE "{target_table_name}" ( - id INTEGER PRIMARY KEY, - {column_names_and_types} - ) - """ - else: - make_table = f""" - CREATE TABLE "{target_table_name}" ( - id INTEGER PRIMARY KEY - ) + query = """ + UPDATE runs + SET completed_timestamp = ? + WHERE run_id = ? """ - - cursor = target_conn.cursor() - cursor.execute(make_table) - - # according to one of our reports, multiple single-row inserts - # are okay if there's only one commit - - column_names = ','.join(data_columns) - value_placeholders = sql_placeholder_string(len(data_columns)) - insert_data = f""" - INSERT INTO "{target_table_name}" - ({column_names}) - values {value_placeholders} - """ - - for row in data_rows: - # the first row entry is the ID, which is automatically inserted - cursor.execute(insert_data, tuple(v for v in row[1:])) - - return target_table_name - - -def _update_result_table_name(target_conn: SomeConnection, - target_table_name: str, - target_run_id: int) -> None: - sql = """ - UPDATE runs - SET result_table_name = ? - WHERE run_id = ? - """ cursor = target_conn.cursor() - cursor.execute(sql, (target_table_name, target_run_id)) + cursor.execute(query, (correct_completed_timestamp, target_run_id)) From 3cdca93cd62264fb7333d7aefc1d971cae88faa5 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 14 Nov 2018 14:53:00 +0100 Subject: [PATCH 093/719] Fix incorrect conn handling in load_by_counter --- qcodes/dataset/data_set.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 18fad27da4b..ccdff6a17df 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -192,7 +192,7 @@ class DataSet(Sized): persistent_traits = ('name', 'guid', 'number_of_results', 'parameters', 'paramspecs', 'exp_name', 'sample_name', 'completed', 'snapshot', 'run_timestamp_raw', - 'description', 'completed_timestamp_raw') + 'description', 'completed_timestamp_raw', 'metadata') def __init__(self, path_to_db: str=None, run_id: Optional[int]=None, @@ -967,9 +967,8 @@ def load_by_counter(counter: int, exp_id: int, """ c = transaction(conn, sql, counter, exp_id) run_id = one(c, 'run_id') - conn.close() - d = DataSet(get_DB_location(), run_id=run_id) + d = DataSet(conn=conn, run_id=run_id) return d From e1817dbdc35487921dc4e461ed89648f0826b965 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 15 Nov 2018 11:26:47 +0100 Subject: [PATCH 094/719] Don't use mark.usefixtures decorator --- qcodes/tests/dataset/test_dataset_basic.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 050f98ade27..9f52c5636c3 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -495,8 +495,7 @@ def fb(xv, yv): assert dataset.get_setpoints("b")['y'] == expected_setpoints[1] -@pytest.mark.usefixtures('experiment') -def test_get_description(some_paramspecs): +def test_get_description(experiment, some_paramspecs): paramspecs = some_paramspecs[2] @@ -528,8 +527,7 @@ def test_get_description(some_paramspecs): assert loaded_ds.description == desc -@pytest.mark.usefixtures('experiment') -def test_metadata(): +def test_metadata(experiment): metadata1 = {'number': 1, "string": "Once upon a time..."} metadata2 = {'more': 'meta'} @@ -558,7 +556,7 @@ def test_metadata(): ds1.add_metadata(tag, value) -def test_the_same_dataset_as(some_paramspecs): +def test_the_same_dataset_as(some_paramspecs, experiment): paramspecs = some_paramspecs[2] ds = DataSet() ds.add_parameter(paramspecs['ps1']) From 501b3abe6c8fca24412f99f0c9b2ee5f1f17a71a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Sep 2018 15:23:21 +0200 Subject: [PATCH 095/719] Add simple prototype of new ArrayParameter --- qcodes/instrument/parameter.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 5c6faac94e5..2b928145439 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -947,6 +947,36 @@ def sweep(self, start, stop, step=None, num=None): step=step, num=num) +class ArrayParameter2(Parameter): + """ + + + + """ + def __init__(self, *args, setpoints=None, **kwargs): + if setpoints is None: + self.setpoints = [] + else: + self.setpoints = setpoints + super().__init__(*args, **kwargs) + + +class GeneratedSetPoints(Parameter): + """ + A parameter that generates a setpoint array from start, stop and num points + parameters. + """ + def __init__(self, startparam, stopparam, numpointsparam, *args, **kwargs): + super().__init__(*args, **kwargs) + self._startparam = startparam + self._stopparam = stopparam + self._numpointsparam = numpointsparam + + def get_raw(self): + return numpy.linspace(self._startparam(), self._stopparam(), + self._numpointsparam()) + + class ArrayParameter(_BaseParameter): """ A gettable parameter that returns an array of values. From 9e622c5c6897722c201c298597635dde83f655eb Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Sep 2018 15:23:47 +0200 Subject: [PATCH 096/719] Handle new array parameters in dataset --- qcodes/dataset/measurements.py | 59 +++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 4e8e47baefb..78d7d68fc60 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -12,7 +12,7 @@ import qcodes as qc from qcodes import Station from qcodes.instrument.parameter import ArrayParameter, _BaseParameter, \ - Parameter, MultiParameter + Parameter, MultiParameter, ArrayParameter2 from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.param_spec import ParamSpec from qcodes.dataset.data_set import DataSet @@ -156,6 +156,10 @@ def add_result(self, *res_tuple: res_type) -> None: self._unbundle_arrayparameter(parameter, res, found_parameters) + if isinstance(parameter, ArrayParameter2): + self._unbundle_arrayparameter2(parameter, + res, + found_parameters) for partial_result in res: parameter = partial_result[0] @@ -288,6 +292,24 @@ def _unbundle_arrayparameter(self, parameter.setpoints, res, found_parameters) + def _unbundle_arrayparameter2(self, parameter: ArrayParameter2, + res: List[res_type], + found_parameters: List[str]) -> None: + setpoint_names = [] + setpoint_data = [] + for setpointparam in parameter.setpoints: + these_setpoints = setpointparam.get() + setpoint_names.append(setpointparam.full_name) + setpoint_data.append(these_setpoints) + found_parameters.append(setpointparam.full_name) + if setpointparam.full_name not in self.parameters.keys(): + raise RuntimeError(f'{setpointparam.full_name} ' + f'which is a setpoint parameter for' + f'{parameter.full_name} is not registered!') + output_grids = np.meshgrid(*setpoint_data, indexing='ij') + for name, grid in zip(setpoint_names, output_grids): + res.append((name, grid)) + def _unbundle_setpoints_from_param(self, parameter: _BaseParameter, sp_names: Sequence[str], fallback_sp_name: str, @@ -631,6 +653,11 @@ def register_parameter( setpoints, basis, paramtype) + if isinstance(parameter, ArrayParameter2): + self._register_arrayparameter2(parameter, + setpoints, + basis, + paramtype) elif isinstance(parameter, MultiParameter): self._register_multiparameter(parameter, setpoints, @@ -726,6 +753,36 @@ def _register_arrayparameter(self, basis, paramtype) + def _register_arrayparameter2(self, + parameter: ArrayParameter2, + setpoints: setpoints_type, + basis: setpoints_type, + paramtype: str) -> None: + """ + Register an ArrayParameter2 and the setpoints belonging to the + ArrayParameter2 + """ + name = str(parameter) + my_setpoints = list(setpoints) if setpoints else [] + for i, setpoints in enumerate(parameter.setpoints): + spname = setpoints.full_name + splabel = setpoints.label + spunit = setpoints.unit + + sp = ParamSpec(name=spname, paramtype=paramtype, + label=splabel, unit=spunit) + + self.parameters[spname] = sp + + my_setpoints += [spname] + + self._register_parameter(name, + parameter.label, + parameter.unit, + my_setpoints, + basis, + paramtype) + def _register_multiparameter(self, multiparameter: MultiParameter, setpoints: setpoints_type, From 876c6e45e7ca23a2344cc383efcd1e349d55da0d Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Sep 2018 15:31:52 +0200 Subject: [PATCH 097/719] Notebook with simple example of new ArrayParameter --- ...Simple Example of new ArrayParameter.ipynb | 505 ++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb diff --git a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb new file mode 100644 index 00000000000..fa609674392 --- /dev/null +++ b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb @@ -0,0 +1,505 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple Example of new ArrayParameter\n", + "\n", + "This notebook has an example of a new simpler ArrayParameter\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument.parameter import Parameter, _BaseParameter" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Optional, Union, Iterable, Callable\n", + "Number = Union[float, int]\n", + "from qcodes.utils.validators import Validator" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.utils.validators import Numbers\n", + "from qcodes.instrument.base import Instrument\n", + "from qcodes.dataset.measurements import Measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument.parameter import ArrayParameter2, GeneratedSetPoints" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we define an dummy instrument that returns something like a frequency spectrum from `f_start` to `f_stop`\n", + "in `n_points` steps. The functionality of the ArrayParameter is implemented only by having a reference to it's setpoints which is consumed by the dataset context manager. To do this we only have to define the parameter for the setpoints and the spectrum and let the parameter know that the frequency axis is the setpoints " + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "class DummyArray(ArrayParameter2):\n", + " \n", + " def get_raw(self):\n", + " npoints = self.root_instrument.n_points()\n", + " return np.random.rand(npoints)\n", + " \n", + "\n", + "class DummySpectrumAnalyzer(Instrument):\n", + " \n", + " def __init__(self, name, **kwargs):\n", + " \n", + " super().__init__(name, **kwargs)\n", + " \n", + "\n", + " self.add_parameter('f_start',\n", + " initial_value=0,\n", + " unit='Hz',\n", + " label='f start',\n", + " vals=Numbers(0,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + "\n", + " self.add_parameter('f_stop',\n", + " unit='Hz',\n", + " label='f stop',\n", + " vals=Numbers(1,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + "\n", + " self.add_parameter('n_points',\n", + " unit='',\n", + " vals=Numbers(1,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + " \n", + " self.add_parameter('freq_axis',\n", + " unit='Hz',\n", + " label='Freq Axis',\n", + " parameter_class=GeneratedSetPoints,\n", + " startparam=self.f_start,\n", + " stopparam=self.f_stop,\n", + " numpointsparam=self.n_points)\n", + " \n", + " self.add_parameter('spectrum',\n", + " unit='dBm',\n", + " setpoints=(self.freq_axis,),\n", + " label='Spectrum',\n", + " parameter_class=DummyArray)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "a = DummySpectrumAnalyzer('foobar')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we setup the limits of the spectrum" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "a.f_start(0)\n", + "a.f_stop(500)\n", + "a.n_points(501)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can grab the axis" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.,\n", + " 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21.,\n", + " 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32.,\n", + " 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43.,\n", + " 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,\n", + " 55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65.,\n", + " 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76.,\n", + " 77., 78., 79., 80., 81., 82., 83., 84., 85., 86., 87.,\n", + " 88., 89., 90., 91., 92., 93., 94., 95., 96., 97., 98.,\n", + " 99., 100., 101., 102., 103., 104., 105., 106., 107., 108., 109.,\n", + " 110., 111., 112., 113., 114., 115., 116., 117., 118., 119., 120.,\n", + " 121., 122., 123., 124., 125., 126., 127., 128., 129., 130., 131.,\n", + " 132., 133., 134., 135., 136., 137., 138., 139., 140., 141., 142.,\n", + " 143., 144., 145., 146., 147., 148., 149., 150., 151., 152., 153.,\n", + " 154., 155., 156., 157., 158., 159., 160., 161., 162., 163., 164.,\n", + " 165., 166., 167., 168., 169., 170., 171., 172., 173., 174., 175.,\n", + " 176., 177., 178., 179., 180., 181., 182., 183., 184., 185., 186.,\n", + " 187., 188., 189., 190., 191., 192., 193., 194., 195., 196., 197.,\n", + " 198., 199., 200., 201., 202., 203., 204., 205., 206., 207., 208.,\n", + " 209., 210., 211., 212., 213., 214., 215., 216., 217., 218., 219.,\n", + " 220., 221., 222., 223., 224., 225., 226., 227., 228., 229., 230.,\n", + " 231., 232., 233., 234., 235., 236., 237., 238., 239., 240., 241.,\n", + " 242., 243., 244., 245., 246., 247., 248., 249., 250., 251., 252.,\n", + " 253., 254., 255., 256., 257., 258., 259., 260., 261., 262., 263.,\n", + " 264., 265., 266., 267., 268., 269., 270., 271., 272., 273., 274.,\n", + " 275., 276., 277., 278., 279., 280., 281., 282., 283., 284., 285.,\n", + " 286., 287., 288., 289., 290., 291., 292., 293., 294., 295., 296.,\n", + " 297., 298., 299., 300., 301., 302., 303., 304., 305., 306., 307.,\n", + " 308., 309., 310., 311., 312., 313., 314., 315., 316., 317., 318.,\n", + " 319., 320., 321., 322., 323., 324., 325., 326., 327., 328., 329.,\n", + " 330., 331., 332., 333., 334., 335., 336., 337., 338., 339., 340.,\n", + " 341., 342., 343., 344., 345., 346., 347., 348., 349., 350., 351.,\n", + " 352., 353., 354., 355., 356., 357., 358., 359., 360., 361., 362.,\n", + " 363., 364., 365., 366., 367., 368., 369., 370., 371., 372., 373.,\n", + " 374., 375., 376., 377., 378., 379., 380., 381., 382., 383., 384.,\n", + " 385., 386., 387., 388., 389., 390., 391., 392., 393., 394., 395.,\n", + " 396., 397., 398., 399., 400., 401., 402., 403., 404., 405., 406.,\n", + " 407., 408., 409., 410., 411., 412., 413., 414., 415., 416., 417.,\n", + " 418., 419., 420., 421., 422., 423., 424., 425., 426., 427., 428.,\n", + " 429., 430., 431., 432., 433., 434., 435., 436., 437., 438., 439.,\n", + " 440., 441., 442., 443., 444., 445., 446., 447., 448., 449., 450.,\n", + " 451., 452., 453., 454., 455., 456., 457., 458., 459., 460., 461.,\n", + " 462., 463., 464., 465., 466., 467., 468., 469., 470., 471., 472.,\n", + " 473., 474., 475., 476., 477., 478., 479., 480., 481., 482., 483.,\n", + " 484., 485., 486., 487., 488., 489., 490., 491., 492., 493., 494.,\n", + " 495., 496., 497., 498., 499., 500.])" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.freq_axis()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or the spectrum" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.31281518, 0.96887871, 0.42191194, 0.51714415, 0.25538286,\n", + " 0.92696486, 0.76954697, 0.51712345, 0.48111713, 0.61014766,\n", + " 0.42801603, 0.43561301, 0.64152132, 0.24845664, 0.68491269,\n", + " 0.57899917, 0.16974739, 0.18945099, 0.77348716, 0.32345713,\n", + " 0.32283512, 0.03025562, 0.91810724, 0.57521798, 0.58470989,\n", + " 0.38120617, 0.46536914, 0.48650925, 0.30560833, 0.78322953,\n", + " 0.93716312, 0.60605105, 0.75239911, 0.96351199, 0.32925186,\n", + " 0.71956489, 0.49513814, 0.40072415, 0.71484636, 0.47744867,\n", + " 0.99183756, 0.42884688, 0.87046585, 0.97636722, 0.80768148,\n", + " 0.47275855, 0.04567205, 0.80345861, 0.16429275, 0.98433221,\n", + " 0.31342919, 0.25533898, 0.71032451, 0.03503889, 0.69431169,\n", + " 0.85934569, 0.15493456, 0.350528 , 0.13867757, 0.88801413,\n", + " 0.12544615, 0.71695272, 0.80233482, 0.95412588, 0.08481348,\n", + " 0.88858004, 0.20740531, 0.62895786, 0.7094034 , 0.71663199,\n", + " 0.04516419, 0.25645949, 0.3619041 , 0.22624793, 0.03096165,\n", + " 0.50486112, 0.38058129, 0.38549274, 0.93265042, 0.69570252,\n", + " 0.9715744 , 0.26551269, 0.0278466 , 0.47564881, 0.14327013,\n", + " 0.65544137, 0.37554881, 0.81038091, 0.4373319 , 0.63655817,\n", + " 0.84999389, 0.48549494, 0.37636679, 0.24317791, 0.46666367,\n", + " 0.93993374, 0.2030196 , 0.20372072, 0.55596547, 0.64384574,\n", + " 0.55032748, 0.18346428, 0.13315848, 0.4444626 , 0.57653102,\n", + " 0.28088507, 0.47296397, 0.19810506, 0.02489858, 0.08292104,\n", + " 0.15122852, 0.02681189, 0.1825864 , 0.83923332, 0.82979598,\n", + " 0.12532781, 0.28667028, 0.06138414, 0.54201822, 0.28361495,\n", + " 0.04006816, 0.55588607, 0.08477299, 0.2226377 , 0.74544186,\n", + " 0.248556 , 0.90649953, 0.09848282, 0.63803225, 0.54836512,\n", + " 0.09148153, 0.14109837, 0.62075636, 0.52826137, 0.8763575 ,\n", + " 0.48961966, 0.24877176, 0.89193214, 0.7763051 , 0.6191885 ,\n", + " 0.93309929, 0.48183231, 0.38190092, 0.76675634, 0.31256475,\n", + " 0.64081171, 0.23996295, 0.17831513, 0.70911486, 0.3689516 ,\n", + " 0.77318391, 0.26551174, 0.9332016 , 0.80833114, 0.94929732,\n", + " 0.05899685, 0.14579488, 0.50757545, 0.84313475, 0.67681984,\n", + " 0.09312281, 0.17850811, 0.30471426, 0.70653125, 0.94016408,\n", + " 0.77204967, 0.78658342, 0.96252718, 0.05135915, 0.6104287 ,\n", + " 0.57842423, 0.54790475, 0.18708696, 0.40089462, 0.61792494,\n", + " 0.78666442, 0.45664661, 0.57400101, 0.21632045, 0.65836317,\n", + " 0.41728132, 0.09314095, 0.39881779, 0.69329242, 0.89670779,\n", + " 0.39077226, 0.36796047, 0.51413186, 0.24017188, 0.96503661,\n", + " 0.39737534, 0.14966974, 0.05272144, 0.07344577, 0.65384573,\n", + " 0.3244456 , 0.93881849, 0.77149932, 0.34256363, 0.57171536,\n", + " 0.99633436, 0.7128691 , 0.53621015, 0.20434432, 0.95889797,\n", + " 0.14452839, 0.52756577, 0.59106331, 0.3081482 , 0.4549849 ,\n", + " 0.20716477, 0.46569662, 0.74935475, 0.43593272, 0.27032474,\n", + " 0.76637407, 0.88225447, 0.65898922, 0.80142354, 0.14939703,\n", + " 0.54069258, 0.78950072, 0.83605732, 0.62979079, 0.21252879,\n", + " 0.60680212, 0.97419554, 0.77182435, 0.75763177, 0.97771958,\n", + " 0.91581111, 0.7219678 , 0.96016159, 0.65960683, 0.23570303,\n", + " 0.33695877, 0.23561085, 0.82518603, 0.94735652, 0.52801753,\n", + " 0.62309437, 0.98345045, 0.35983667, 0.07843121, 0.09146102,\n", + " 0.66973072, 0.93494067, 0.05280839, 0.93756376, 0.7293141 ,\n", + " 0.50768684, 0.14962689, 0.2658266 , 0.27975887, 0.96575044,\n", + " 0.86352484, 0.00677849, 0.60706878, 0.60814407, 0.12029253,\n", + " 0.34831538, 0.34223691, 0.58388414, 0.681435 , 0.21728724,\n", + " 0.94635087, 0.33127465, 0.64361487, 0.92241564, 0.59245856,\n", + " 0.1148949 , 0.7021584 , 0.11996621, 0.64843461, 0.94555061,\n", + " 0.70387657, 0.77887487, 0.72795828, 0.68279723, 0.39879606,\n", + " 0.1533654 , 0.38515401, 0.71375073, 0.17799896, 0.0252395 ,\n", + " 0.06283647, 0.84102243, 0.45017289, 0.29994363, 0.58409358,\n", + " 0.80281348, 0.79188333, 0.1162714 , 0.32685503, 0.75942253,\n", + " 0.38373489, 0.79152529, 0.97062294, 0.67297296, 0.79336539,\n", + " 0.43884364, 0.24561457, 0.65555045, 0.87768973, 0.64103826,\n", + " 0.2666453 , 0.1391131 , 0.86647697, 0.61714395, 0.41203585,\n", + " 0.11707366, 0.95913778, 0.05950737, 0.74316187, 0.24973516,\n", + " 0.55441886, 0.19049959, 0.72943378, 0.14485682, 0.23767495,\n", + " 0.23655284, 0.75358185, 0.11639362, 0.22699845, 0.58859088,\n", + " 0.19922609, 0.59756317, 0.31772437, 0.31891757, 0.61702834,\n", + " 0.2307571 , 0.71656227, 0.77801287, 0.61430522, 0.43949158,\n", + " 0.904222 , 0.13305298, 0.97109297, 0.03946522, 0.27349123,\n", + " 0.60728714, 0.11184083, 0.20264691, 0.41851126, 0.34208404,\n", + " 0.3516932 , 0.72207464, 0.62215237, 0.83973124, 0.61972589,\n", + " 0.00746499, 0.67415024, 0.64700587, 0.31843831, 0.85093758,\n", + " 0.36074848, 0.26198126, 0.55974394, 0.7755382 , 0.96214801,\n", + " 0.60038967, 0.5871515 , 0.97103239, 0.25660708, 0.8394608 ,\n", + " 0.61362974, 0.7721306 , 0.41902284, 0.56507279, 0.97512555,\n", + " 0.1757342 , 0.12194126, 0.72601828, 0.46489845, 0.20108013,\n", + " 0.12265486, 0.32739885, 0.23558657, 0.02516245, 0.90309388,\n", + " 0.71132001, 0.35639495, 0.99692481, 0.13415441, 0.65833817,\n", + " 0.11460708, 0.51822322, 0.53973366, 0.81536775, 0.13440548,\n", + " 0.48233264, 0.25445079, 0.00434424, 0.84816563, 0.02711536,\n", + " 0.21425029, 0.07758158, 0.02883053, 0.56527235, 0.19727065,\n", + " 0.49378938, 0.66257068, 0.99112211, 0.49515019, 0.45807055,\n", + " 0.24407957, 0.80594336, 0.52918217, 0.7366867 , 0.12172603,\n", + " 0.50720039, 0.89600683, 0.03299381, 0.87402446, 0.03942597,\n", + " 0.4398926 , 0.56602433, 0.1827016 , 0.34461014, 0.48292586,\n", + " 0.37908904, 0.05441919, 0.20705179, 0.34375954, 0.6649455 ,\n", + " 0.0731173 , 0.10959237, 0.98139206, 0.03566843, 0.00688507,\n", + " 0.91668891, 0.91156237, 0.65782263, 0.15321753, 0.12761921,\n", + " 0.70015197, 0.5353978 , 0.48899851, 0.92041438, 0.58646024,\n", + " 0.24802929, 0.58023147, 0.51882816, 0.49366176, 0.03196893,\n", + " 0.56670287, 0.06277128, 0.54048722, 0.85678255, 0.31840659,\n", + " 0.60387901, 0.25282476, 0.62576788, 0.34045001, 0.78477856,\n", + " 0.19135518, 0.89802393, 0.56130128, 0.54358126, 0.70889138,\n", + " 0.23780924, 0.43899571, 0.04051872, 0.73162057, 0.7630328 ,\n", + " 0.42628733, 0.5824199 , 0.51831109, 0.5821532 , 0.01817897,\n", + " 0.20330086, 0.02747431, 0.15170385, 0.63457024, 0.30606336,\n", + " 0.15690499, 0.75987837, 0.87250445, 0.34596773, 0.35767279,\n", + " 0.42499385, 0.14849033, 0.79368317, 0.08853673, 0.87720111,\n", + " 0.3156627 , 0.73408487, 0.16822168, 0.13283555, 0.35081781,\n", + " 0.23496507, 0.11859108, 0.19449802, 0.8220064 , 0.30034061,\n", + " 0.61608037, 0.64891939, 0.15747444, 0.40561231, 0.23300349,\n", + " 0.11877202])" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.spectrum.get()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also directly consume the parameter in a measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 614\n" + ] + } + ], + "source": [ + "meas = Measurement()\n", + "meas.register_parameter(a.spectrum) # register the first independent parameter\n", + "\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((a.spectrum, a.spectrum.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.dataset.plotting import plot_by_id" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And plot it" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 3b90878b6aea45161e3f9201fafede0ab802e9f6 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 12 Sep 2018 18:13:44 +0200 Subject: [PATCH 098/719] Add raw arrayparameter time/freq example notebook --- .../examples/DataSet/Simple Example of new ArrayParameter.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb index fa609674392..ba8cdbc751f 100644 --- a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb +++ b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb @@ -455,7 +455,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.6.5" }, "toc": { "base_numbering": 1, From 30e21e2a32f30e186a0cc134365dc862ba882b1f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 12 Sep 2018 18:17:00 +0200 Subject: [PATCH 099/719] Add example notebook of time/freq measurement --- ...arameter Example with Dual Setpoints.ipynb | 411 ++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb diff --git a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb new file mode 100644 index 00000000000..7c53af62806 --- /dev/null +++ b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb @@ -0,0 +1,411 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# An ArrayParameter Example with Dual Setpoints\n", + "\n", + "In this example we consider a dummy instrument that can return a time trace or the DFT (magnitude square) of that trace. The setpoints are accounted for in an easy way." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "from qcodes.instrument.base import Instrument, Parameter\n", + "from qcodes.instrument.parameter import ArrayParameter2\n", + "from qcodes.dataset.measurements import Measurement\n", + "from qcodes.dataset.plotting import plot_by_id" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def timetrace(npts: int, dt: float) -> np.ndarray:\n", + " \"\"\"\n", + " A very realistic-looking signal\n", + " \"\"\"\n", + " #freq = 10/(dt*npts)\n", + " #decay = 1/(dt*npts)\n", + " freq = 10\n", + " decay = 1\n", + " time = np.linspace(0, npts*dt, npts, endpoint=False)\n", + " signal = np.exp(-decay*time)*np.sin(2*np.pi*freq*time)\n", + " noise = 0.1*np.random.randn(npts)\n", + " return signal + noise" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "class TimeTrace(ArrayParameter2):\n", + " \n", + " def get_raw(self):\n", + " npts = self.root_instrument.npts()\n", + " dt = self.root_instrument.dt()\n", + " \n", + " return timetrace(npts, dt)\n", + " \n", + "\n", + "class Periodogram(ArrayParameter2):\n", + " \n", + " def get_raw(self):\n", + " npts = self.root_instrument.npts()\n", + " dt = self.root_instrument.dt()\n", + " \n", + " tt = self.root_instrument.trace()\n", + " \n", + " return np.abs(np.fft.fft(tt))**2\n", + " \n", + " \n", + "class TimeAxis(Parameter):\n", + "\n", + " def get_raw(self):\n", + " npts = self.root_instrument.npts()\n", + " dt = self.root_instrument.dt()\n", + " return np.linspace(0, dt*npts, npts, endpoint=False)\n", + "\n", + " \n", + "class FrequencyAxis(Parameter):\n", + " \n", + " def get_raw(self):\n", + " npts = self.root_instrument.npts()\n", + " dt = self.root_instrument.dt()\n", + "\n", + " return np.linspace(0, 1/dt, npts)\n", + " \n", + " \n", + "class OzzyLowScope(Instrument):\n", + " \n", + " def __init__(self, name, **kwargs):\n", + " \n", + " super().__init__(name, **kwargs)\n", + " \n", + " self.add_parameter(name='npts',\n", + " initial_value=500,\n", + " label='Number of points',\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + " \n", + " self.add_parameter(name='dt',\n", + " initial_value=1e-3,\n", + " label='Time resolution',\n", + " unit='s',\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + " \n", + " self.add_parameter(name='time_axis',\n", + " label='Time',\n", + " unit='s',\n", + " parameter_class=TimeAxis)\n", + " \n", + " self.add_parameter(name='freq_axis',\n", + " label='Frequency',\n", + " unit='Hz',\n", + " parameter_class=FrequencyAxis)\n", + " \n", + " self.add_parameter(name='trace',\n", + " label='Signal',\n", + " unit='V',\n", + " setpoints=(self.time_axis,),\n", + " parameter_class=TimeTrace)\n", + " \n", + " self.add_parameter(name='periodogram',\n", + " label='Periodogram',\n", + " unit='V^2/Hz',\n", + " setpoints=(self.freq_axis,),\n", + " parameter_class=Periodogram)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "osc = OzzyLowScope('osc')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Measurement 1: Time Trace" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 68\n" + ] + } + ], + "source": [ + "timemeas = Measurement()\n", + "timemeas.register_parameter(osc.trace)\n", + "\n", + "osc.dt(0.001)\n", + "\n", + "with timemeas.run() as datasaver:\n", + " datasaver.add_result((osc.trace, osc.trace.get()))\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 69\n" + ] + } + ], + "source": [ + "osc.dt(0.01) # make the trace 10 times longer\n", + "\n", + "with timemeas.run() as datasaver:\n", + " datasaver.add_result((osc.trace, osc.trace.get()))\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(dataid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Measurement 2: Periodogram" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 71\n" + ] + } + ], + "source": [ + "freqmeas = Measurement()\n", + "freqmeas.register_parameter(osc.periodogram)\n", + "\n", + "with freqmeas.run() as datasaver:\n", + " datasaver.add_result((osc.periodogram, osc.periodogram.get()))\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 72\n" + ] + } + ], + "source": [ + "with freqmeas.run() as datasaver:\n", + " datasaver.add_result((osc.periodogram, np.log10(osc.periodogram.get())))\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(dataid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Measurement 3: 2D Sweeping" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 77\n" + ] + } + ], + "source": [ + "meas = Measurement()\n", + "meas.register_parameter(osc.dt)\n", + "meas.register_parameter(osc.time_axis, setpoints=[osc.dt])\n", + "\n", + "with meas.run() as datasaver:\n", + "\n", + " for dt in [0.01, 0.02, 0.03]:\n", + " osc.dt(dt)\n", + " datasaver.add_result((osc.time_axis, osc.time_axis.get()),\n", + " (osc.dt, osc.dt.get()))\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 38cdf9f0e44582d67fd408cbc8dd6953161094ea Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 13 Sep 2018 09:05:47 +0200 Subject: [PATCH 100/719] Update notebook example to look crisp --- ...arameter Example with Dual Setpoints.ipynb | 83 ++++++++++++------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb index 7c53af62806..a58fd20b436 100644 --- a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb +++ b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb @@ -21,7 +21,7 @@ "from qcodes.instrument.base import Instrument, Parameter\n", "from qcodes.instrument.parameter import ArrayParameter2\n", "from qcodes.dataset.measurements import Measurement\n", - "from qcodes.dataset.plotting import plot_by_id" + "from qcodes.dataset.plotting import plot_by_id, load_by_id" ] }, { @@ -156,7 +156,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 68\n" + "Starting experimental run with id: 101\n" ] } ], @@ -179,9 +179,9 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYkAAAEWCAYAAACT7WsrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXeYJFW5uN+v0/Tkmc2J3WXJS1hYliBBMgISFEFFroqg/AyYrlcvKoYroqh4Va5cFFHEi6IoqAiScxLYhWVZll1Y2Jx3ZyenDuf3R1X1VNd0z/TMdKWe8z7PPNNdXd11qrvqfOfLopRCo9FoNJpCRPwegEaj0WiCixYSGo1GoymKFhIajUajKYoWEhqNRqMpihYSGo1GoymKFhIajUajKYoWEhpNGRCR10TkRL/H4URE5oqIEpFYCft+W0RuG+L1KhFZISLTzee/FZHvlnO85ueuFZFTy/RZd4rImeX4rPGKFhIVhHlz9YhIp4hsNW/iOg+O+2kR+Z75+EkROcTx+jwRuUdEOkRkp4j80PbaXBH5p4jsNsf881ImNPO93xaRlHm+1l9rec+uNJRSByqlHvf6uCLyuIh83KPDXQ48qZTa4tHxRkQRIfcDoOyCbDyhhUTlcY5Sqg44FDgM+KoHxzwcWCwiEWB/YIX1gogkgIeAR4FpwCzAfiP/L7AdmG6O+QTg0yM49p+UUnW2v6YxnckIKVWgVQifBP7P70GMBKXUC0CDiCzyeyxhRQuJCkUptRV4AGPiBQavOkXkEhF52vZcicgnReRNEWkVkRtEREo43CJgCbAfsFYplba9dgmwWSn130qpLqVUr1Jqme31PYE7zO1bgfuBA0dxynmIyDGm1rKH+XyBqa3sbz5fKyJfNc0nu0XkFhFJ2t5/togsNb+HZ+3akfne/xSRZUCXiMTsJhJzRftnEbnN1J5eFZF9zeNtF5ENInK67fMaReTXIrJFRDaJyHdFJGq+domIPC0i15njXGOZT0TkGuB44OemFvXzEr6XGSJyt4i0iMhqEflEid/nbGAe8LzjpUki8pB5nk+IyBxz/0FmrgLX3ydE5HXzvStEZGGB4x5gnvNFtvHfKSI7zO2fM7efAXwN+ID5Xbxi+5jHgXeXcp6awWghUaGIyCzgTGD1CN96NnAEcAjwfuBdRT6/ypxA24CDgFcwBMUCc/vXzV2PBtaKyH3mpP24iBxs+6ifAh8UkRoRmWmO+f4RjnkQSqlngV8Ct4pINYb28g2l1Erbbheb57cXsC9wlXluhwG/Af4fMNH8nLtFpMr23oswJp4mh1C0OAdj1d0MvIwhsCPATOA75mda/BZIA3tjaH+nA3YT0lHAKmAS8EPg1yIiSqmvA08BV5ha1BUlfDV/BDYCM4ALgO+JyMklvO9g4O0C53oxcLU5tqXA70v4LETkQuDbwEeABuBcYJdjn4UY39tnlVK3m5rqPzCutZnAKcAXRORdSqn7ge8xoFkusH3U64D9uWYEaCFRefxNRDqADRhmnG+N8P3XKqValVLrgcewaSJ2lFJ9pmnnS8D15uOngeOUUk1KqWvMXWcBHwSux5iY7gX+bpqhAJ7E0BzaMSavxcDfRjDe95tCyfp7zPbat4FG4AVgE3CD470/V0ptUEq1ANdgTPxg2N5/qZR6XimVUUrdCvRhCDyL68339hQZ11NKqQfMSfXPwGSM7zaFMVHPFZEmEZkKnAV8wdS0tgM/wfjOLNYppX6llMoAt2KY5qaW/hUZmFrVscB/mprbUuBmjIl6OJqAjgLb71VKPamU6gO+DrzD0t6G4ePAD5VSLyqD1UqpdbbXjwfuBj6ilLrH3HYEMFkp9R2lVL9S6m3gV+R/V4XoMMevGQVaSFQe71FK1QMnYvgHJo3w/Vttj7uBgo5vEfmjGE7iG4GPmxrFKcBDIvKCbdce4Gml1H1KqX7gOozV+QHmyvB+4C6g1hxrM4azsVTuMIWS9XeS9YI5If8WQ9P5sRpczXKD7fE6DCEGMAf4kl34AHvYXne+txDbbI97gJ3mJG89B+O7nQPEgS22Y/0SmGJ7f+43UUp12947UmYALUop+2S/DmNVPhy7gfoC23Pfg1KqE2gh/3sqxh7AW0O8/kngWUcwwBxghuN3+RrDC8x6wJeAhkpAC4kKRSn1BMYEeZ1tcxdQY3s+bQyf/0GMyX43xirtI8Dt5kR9pG3XZUCxUsMTgNkYK/o+pdQu4BaMlfWYMc1X3zI/88cOcxEYE5XFbGCz+XgDcI1D+NQopW637V+u8skbMLSUSbZjNSilSvXLjGQcm4EJImKf7GdjaFnDsQzYUwY76nPfoRiRdBPM43SZm4tdbxswzHzF+CQwW0R+4njPGsfvUq+Usq6XYt/FARgmKs0o0EKisvkpcJqIWPbYpcD5pv1/b+CyMX7+/sBb5gp5IYapyMltwNEicqrpjP0CsBN4XSm1E1gDfMp0/jYBH8WYkICck/iSkQ5MRARDSP4a4zy3YNjO7XxGRGaJyAQMU8mfzO2/Aj4pIkeJQa2IvNsxuZYFM5z0QQwh1iAiERHZS0ROKPEjtmE4lEs51gbgWeD7IpIUwxl/GfnRZsXeuxHDv3Wk46WzROQ403x4NfAv0wy3A0P4/JuIREXkUvKFws3Af4jI4eZ3vLfl9DbpAM4A3iki15rbXgA6xAgaqDY/9yAROcL2Xcw1NVQ7JwD3DXeOmsJoIVHBmDfq74Bvmpt+AvRj3Ey3UqKTcQgOB14yHy/EcFw7x7AK+DfgFxhax3nAuabpCeB8jMlgB8YklAK+CLnw2YnAv4YYgxXNYv+bAnwOw2TzDdPM9DHgYyJyvO29f8CYoN/GMH181xzzYuATwM/NMa/GiNJyi48ACYzQ4d3AXzD8DqXwM+ACMSKfri9h/4uAuRir/b8C31JKPVzisX4JfNix7Q8Y2loLxvXwb7bXPgF8GcMhfSCGgAJAKfVnDD/QHzAEwt8wtBBs+7QCpwFnisjV5mLkbAw/2RqMxcbNGH4nMHw/ALtE5CUAU4B0mqGwmlEguumQJqiIyHHAZ5RSFw2788g/ey3w8RFMkOMe01z3MnBKUBPqnIjIncCvlVL/9HssYUULCc24RAsJjaY0tLlJo9FoNEXRmoRGo9FoiqI1CY1Go9EUJfTFySZNmqTmzp3r9zA0Go0mVCxZsmSnUmrycPuFXkjMnTuXxYsLhedrNBqNphgism74vbS5SaPRaDRDoIWERqPRaIqihYRGo9FoiqKFhEaj0WiKooWERqPRaIqihYRGo9FoiqKFhEaj0WiKooVEiby5rYNnVu/0exgajUbjKVpIlMhpP3mSi29+nkxW8cKaFrJZXfNKo9FUPlpIjJA/PL+O9//yOa5/9E2/h6LRaDSuo4VECdgr5T64wuhvf8+yUPRc0Wg0mjERKCEhIr8Rke0istzvsdjZ3tGXe7x8UxsAq7d3+jUcjUaj8YxACQmMxvVn+D0IJ69tbss93t2dyj3WvTgqk7d3dHL1PSu030mjIWBCQin1JEZD9UDx15c301QTZ89JtXnbO/vSPo1I4yafvG0Jv356DW/v7PJ7KBqN7wRKSASVVza0cvw+k5lcX5W3vdWmVYwHelMZslnFptYeHl25ze/huEbG1CC0pqjRhLSfhIhcDlwOMHv2bNeP15PKUFcVo78mnre9tTvFHhNcP3wgUEqx/zfu5/zDZvLIyu209aRYe+27/R6WK0QjAoC2Nmk0IdUklFI3KaUWKaUWTZ48bGOlMdObypCMR2iuSQAwd2INAG/t6GRXZ99Qb60YelNZAO56eRNtPYYGVakrbcESEpV5fhrNSAilkPCavlSWqliU7v4MACfsawimL/xpKe+49lE/h+YZlmCw05/J+jAS9xFDRmghodEQMCEhIrcDzwH7ichGEbnM7zFlsor+TJZkPMLu7n4AjthzwMbUn85W7IraztINrYO29aUrU0hETCmRylT+76rRDEegfBJKqYv8HoOTvrShPSTjUb559nx+88xaTj1gat4+m1p7mNVc48fwPGHJuhY+eduSQdv7UllI+jAgl4mYS6dUhWpKGs1ICJQmEUQsW3wyFmGfqfV8//yDScajfOm0fTl+n0kA/PPVLbSaWkYlsqWtt+B2S4BWGjlNokI1JY1mJGghMQy9qQFNws5nT9mHH1+4AIDv/XMlF/ziOc/H5hU1iWjB7ZVqbhJTSFSqz0WjGQlaSAxDMSEB0GRGO8FAmY4dHX0VkWS3ZN1u1prJZJY25aSvyPawY0bA0l+hQlCjGQlaSAzB61vaeWzVDgCS8cFfVSI2eNsR1zzMWT97yvWxuc37bnyWE697HICe/sJmpYo3N2UU2zt6tbDQjGu0kBiC//d/S7j6nhUAVBXQJIqxvqXbrSH5QneqsDCoxMlz2cZWlqzbbTze1MqR1zzCzx9b7fOoNBr/0EKiCOlMNm+yT8aGFhKFNI1KodfUJC46Mj+7vRJ9Euf+/Jnc41ueXgvAU2/u8Gk03vMff36FuVfe6/cwNAGicme2MfKLJ97Kez6cEKhNxCo2X8JKIvz30/bN216JQsKO5bje1Vm5kWtO/rJko99D0AQMLSSK8Jtn1uY9L+S4tlNbFauYSdMp7HpSGRLRCLVV+d9BpfoknKxv6aarAoIRRoIuk66x0EKiAEopOnpTfOrEvXLbigmJ+dMbAIhFpaiDN2w4Qz+t2lWJaP7lUqnRTYXY1Nrj9xA8pZgfSjP+0EKiAH3pLKmMoq5qICG9mLnpD584iv2n1dOXytJTITeWXSPKZhXd/WlqEjFiTiFRIZrTUExtMMrD7+gYH4UcLTp7x5fmpCmOFhIFsPIc6pM2IVHEcd1Uk+DwOc30pjKVIyRsGsJL63dzx+KNxGMyaL/+CjE3fevvy7n8d4sLvjZvUh0AX/zT0nElKDr7xlevFE1xtJAogLWKqk3EeKdZ8XUon0R1PEpPKlMx5ia7r+Hzf1wKwIaWweaWStEkbn1uHQ+uKNxEad5koxvh9o4+rn/kTS+H5SsdWpPQmASqwF9QsDSJumSMGy9eyJvbO6kuUpoCDAFSKZpEJqv4yl+WlbTv9+9bybTGJOcdOtPlUfmHvXBjs6PpVCVTCVUDNOVBaxIFyJmbqmLUVsU4dI+mIfevTkTJKmgv0HMhbLyxrYNn39qVe54ZJsrlugdXuT0kX2msHhAMzbWJIfasLLRPQmOhhUQBrBukLlmaolVllufYXQE9r50ryK3tRgXYhbMLC8rWrvCfs0WhPJeG6oFroFLMa07s4a5W69adnX25umXjgWxWjSuf00jQQqIAOXNTVWlCwjJF3fzU266NySu2tw/cKJbwO2m/yfz5k8fk7Xfh4bOYN6mWjr50xeQQFGoyNLUhyV2fNs69EkN+X16/m3lf+ycvrm0BIB41hMQ3/v4aR17zsJ9D85Qbn3iLI655eNyFOpeCFhIF6OgbmSZhRT6t3NqR2/ZvNz9f/oF5wPaOgd4RZx40DYB0VuVWmIfMauSA6Q386MIFfPaUvYEBbSPsFPIpzZ/ewMLZzSSiEXorJJrLzsvrjY6Dl/32Rba39xK3hTm396a579Utfg3NUx58bSsA2yvkWi4nWkgUwDI31VeV5qiMF6gG+/TqnWUdk1dst6ncVmSX3ddy9xXHcd/njweMVTbAtiJNicJGIY2o1tQmq2KRijS/TDHzQNp703z1rlcHZVp/6vcvVXSHvkxWce+yLTlTolUBWDOAFhIF6O5PI1J60b4T95vMV8/c3+VReYPd3HTwzEY+c9Je/OCCQwruawmJMGsSdj9EmyPw4NO2jPuqeLQifRJ2mfDqpja6CoRxb9pduSaYnz3yJp/5w0s5K0AlLgTGihYSBUhlFPFoJNehbDgaknH+3wl7ceenjhl+5wCjlGLpht2558l4lC+/a3/2n9ZQcP/J9cYqNMwF8Ox+iFZb4MG8ybV85YwBwV+pmkSf7Zy2F3Hcrt3V5dVwPOePL6zPe24vR6KUIl3BWlSpaCFRgHQmSywycrXz8DnNfOWM/VwYkTes2NLOWzsGJoSqAmY0O/VVMWIRYXeI+3vb/RB2TcIZ6JSMRypSkyilReu6XZXVH8Uik1V5CwPIb7D17btfY++v31ex1Z1LRQuJAtgdtSPFWQQvTNz9yuY84Vg1TA8NEaGpJhFqIdGbJyQGziPrmBiqYtG8VXelYEVsWVFNhai0JloWm1t7BgnJZ9/amcsNuvW5dYAxH4xnwjujuUgmq/KiPEaCvaVp2Mot3798K8ftMynnsK4qwSczoTZOS1dlCIm1thWzM4kwGY8U7fUdZqxJsiFZPEhjd4h/30K0dPXz73cs5ZHXjVIs9vXgbf9az01P5oeyV2IHxpGgy3IUIJ3NjlqTiEUGJtb+TJZkpPS2p37S3Z9m3a5uLjx8Fh87dk/e3tE1bA8NgOaaRKiTCO3mphsfH2g0NdjcFK3I/hmWJtFQHWdXEWHQWgGVBOy8tG43d720ibte2gTAMXtNyotGXN+S74PpT2eprfJ0iIFCaxIFSGcU8VEKiXR2YNVRir03KKzZadwY8ybXUVsV4+BZjSW9r7kmwQtrWrjlmTVuDs81ihVlHGxuGtAkHl6xbVAkVFjpz2SIRWRI/1OYzYlOlFLs7MxPGD1270l5+zi1qkr0RY0ELSQKkMkqokPYaIfCrpqGSU1923RY7zmpdkTv6+o3cgv+6x8ryj4mN+lLZ+hPF+8B4hQSVhHH9bu6+fjvFnPcDx4NvUNz4+5u/vTiBhKxyCDNyU5biDVFJ1/801KuvOvV3PPaqhiHz2nO2+eXT77NP21JhGG6j91AC4kCpLIqz2w0EuzaQ5hWIG9u60Bk5ELCXqoiTCGiJ/7ocU780WNFx+x0J1XFjOimt3Z0AkYp7WLmmTCQzSqO+8Fj7OzsJ6sUiuJSolI0ibbuFH9bunnQ9kMKaM2f/v1Lucf9mfBc126ghUQBMtnRhcACpNIDN1uYViAPrtjGYXs0leSHsPOjCw/hOFNd3/8b93PPssE3YRDZ0tbL5rZeXtvUnrfdCmF2agnJeJTdXf05IQHhDg2150T0p7M5TeI/Tt93UNXjtp5U6IIwCtFRpJFSMh7l+a+dUvR9YVrsuYEWEg6WrNvNv95uGbXj2h4UFRYhsbm1h5VbOzjr4Okjfu+cibV88bR9c8+//8+V5RyaK9ijsR5dtZ0Gs0ZXfVWM9y/aAxisSXT0penoS/Pde1/PbVsX4iQze7XfrCKnR+wxoWbQvlk1UM8szBS6H2c1VwMD1QNKfd94QgsJk2ff2sl/P/QG77vxWVq6+omN0idx2XHz2Heq0fIyLBfXBjMOfr9p9aN6f2P18L3Ag8Qb2wYKMb68vpWFpk26Phmj2tSkjpibb6c+Zq+Jucf7T6tHJNyaRHd//qRvaU7O3JiT9jPCoSshDNYZSPL98w/mlx8+fPj3heQ+dovg39Ee8aFfPZ/XnnK0PonqRJSvv3s+EB5b5hazQN/0xuKrqaGot0WDjNRc5QfOWkRzJxp+mC+dvh+1VTHu/8Lx/PQDh+Xtc/FRczhgulGeZHpjkqn1yVCXle7qy782LU2iOhHFqkZz3YUL+Pyphpa4ZN1uwo7dFAxw0ZGzmd5YnXt+7+eOK/i+MEUpuoHOkyjCaH0SMJB1HRZbpiUkptlumJHQEDIh0e1wVk+ur2Ltte/OPS9Wq8rSmJpqEjTVxEMdBjuo4q05fyZtobBVsQgLZjUyozHJA69t5X2Hz/JwhOVnuEXbgTMKh31rTUJTkNH6JGAg6zosF9fWth7qk7GSmyw5sZuYwmBu6nGYWmqG6F9ux2pl2lQTp6E65ELCaW4y/9uFfCJmFLk8eFZj6Iv8PbpyG++78bnc85Fc62G5j90i+He0T4y2LAcMFMYLy8W1cXcPM0apRQB51XKTw9R7CgLdjgS62kRpE4a1X3NNgsbqeKh7mju/A8snkYxHsX5NSyOeUGtk1V/1t1f5xyvhiF5zYmVXA/zgfQfz6H+cUPJ7x7u5SQuJIpRFkwjBxbVqawePrdrOUfMmlOXzwmBu6unP5GUY11SVNmZrtd1cE6chGWfNzi427g6n89op4Kxzsxf6sxZKTTUJdnX2cdu/1vPZ21/2aohlxb5gmz+9kSn1Q/vf7N9DJbatHQlaSBShHD6JMGgSr25qI6vgkmPmluXzImP43ryiuz+TZ2IqVZOwVtvViRiN1XH60lmO+8Fj/PsdS/PqPgWdXz7xFt+/Lz9U2cqTsGuF1kTZXBMfFBIcNuzd9RLDlMAHo56TxVfuXFYR0V2jxTMhISJniMgqEVktIlcWeP0SEdkhIkvNv497NbZCjDYEFgYuQnvP66BiZRyP1h/hpD8ERfAMITFwvqX6JKyJMiID/gkwTBk/uD/4+SFglCNxCogj5jZz6bFzAcOJbwkKS+A31yRy+45l8eQn/SMUEg3V+fWb7h0nvb4L4Ul0k4hEgRuA04CNwIsicrdSylnw509KqSu8GNNwjDYEFgYuwpuefJvPnLR33oQSNCwhUVUmM1EYtKeeVJpquyZRooCcaSZeNdcmBjWrCQvOUNaVV59BLCLEohEuOXZPgJxPwtIu7ELC6kYYNuzX5VC9MyysBEuL6hCYUd3CK03iSGC1UuptpVQ/8EfgPI+OPSrG4pOw27u3tgW3//MTb+zIZRCPNSrp0S+dQDQiee1Ag4rT3FRdoibxhVP34X8uOowT950cmvBmO+29KS655cW8azsZjxIbJkijuXZgkTOW+8JP+m3XZSmaRL2jEuxYLAthxyshMRPYYHu+0dzm5H0iskxE/iIie3gztMKU2N66IPXJOCeamapb24MrJD76mxcAw3wy1o568ybXceTcCaHQJLr7M3krw1J9ElWxKOcsmIGIlDTRBI2tbb30p7Mj9j/ZNeHOkJbnsF+XpVzrThOkM/lwPBGkK/0fwFyl1CHAQ8CtxXYUkctFZLGILN6xY4crgxmro+7q8w4CYFuAhYSFFQ8/VuKxCH0hiOjqcWgSpUY32fnw0XOYWJsYfscAYYW9Hrf3JH5zySJ+9sFDC+5n1fCy6hrNnVjLB4/Yg7MOnkZHb5obHludK+USZB54bSuX3PICvalMnq+sFAHv1KwHJR+OI7wSEpsAu2Ywy9yWQym1Sylllaa8GShaVEUpdZNSapFSatHkyZPLPlgY3E9gpFi22+0hEBLlilxJRCMh0STS+Y7rUdibE7EIlx63ZzmH5TpWvaZkPMrJ+0/lvEMLKfPwsWPnsvy/3sWMJkNIxKIRrn3fIRwyq4lMVvGjB1Zx2a0vejbu0fL//m8Jj6/awcbd+b2sS9EknKHcYdWgyoFXQuJFYB8R2VNEEsAHgbvtO4iIvQTpucDr+MhYG8ok41GaauJsa+8bfmefKVcZ6KpYhP50ht1d/azdGdwM3Z7+DNWJKFeeuT/VJdjkizFUN7eg0d6byvVuHi6aS0QKRrvZt7X3BHvSTGfy+5x09g6MtxS/ivO31ZqEyyil0sAVwAMYk/8dSqnXROQ7InKuudvnROQ1EXkF+BxwiRdjK0a2DAviqfVJtncEX5PIlKnDWiIWIZVRnPTjxznxusfL8plu0J0yzE2fPGEvXr/6jFF/TpiExNX/WMHjqwzTbKkhv07qbRE/5bpm3MIeWNCTyuT16S7FtHrY7GamNlRx9XsOIiKDy5iMJzy7ypVS/1RK7auU2kspdY257ZtKqbvNx19VSh2olFqglDpJKeVr4PlYzU0AjTXxUIRKlut+t8xN1jnPvfLevH7CQSCbVXT1pUsOex0KZ1ntILcz7bCtpEuN5nJiFxJBPlfIFxJb2npHfI031cR5/mun8uGj5zC9sZrbX9jA0g2tZR5lOAjPUshlnCpoOSwwTQEvAjfWiKZBnxeLDCpFErSeC7u6+kllFNOGaDJTKlUO52aQw2LtgmG0Mf91VQNRTkHPwLa3pXWWhi8F+71hlYT/zj9eG/vAQogWEiZOM2U5VkpNAdckSkkqGtnnFXJcB2s22TrG3hl2nOamIPf4tjtia0oM+XWSZ24KuJSwC+y3bS1nS6VQgc85E0fW/71S0EKiCOW4BZpqEoHWJOJltqknYpFBUSBBm0s2txmrwuljqHpr4TQ39QRYSNi1h9EmTtod1+Uwx7qJXWD/ecnGEb+/UJisPfN8PKGFBIbW4MwULsdKqbE6Tk8qQ28qw87OvsAVCXPD3OQkaHNJTpNoKr8m0dMfTCHx9o5Onn1rZ+75aHNi7M2lyhUR5xZjNf3Za1TdeumRgFHOZTyihQSQNi/4E/adzI8uOAQok+PazFRt70mx6LsPc9jVD435M8vJWHpmFGJHx2AndTpgyXVb2npJRCNMKMOq0OmT6A1oSemTf/xEWYpN1tqSDrv6M/zkoTcCa2Ib67jsgvSEfSez56TacZt1rYUEA2WEj9lrIlPL4NC0aKoxhERrQE1O5Q7hbO02NKVzFszIbQuaM7etJ0VDdbwsJc2d5qb/qnDHpjOf5GePvMlzb+/yaTRD47zuLn/nPH584QK+dc78Id938MzCLUxrEtFcMuJ4Q/e4ZqBBejwaydVsKocm0VRtrFaD7LwuJ988Zz5Hz5sIkOtg1hew0uF9qUzZWqw6hezza1pQSpWlxElY6A7o6tqpSVx05Gz2nDS84/n2y48uaBauTcS0JjGescI247EIEfMGL0cynaVJBNV5nTJP8u+fObYsnze9sZqPHjM3zzcRNE2iN50pW/c8S5OoikWYaZawaO8dX6vNoK6unUKi1H4pdVUx9phQM2h7TdX41SS0kGDA3JSISlk1CcsnYZlhgkY6o3j/olks2KOprJ9r93UErfVjbypbtt4AljCsSUT52lkHALC5deQx+V7i7JMwWj514l5AcCO6nIuT+jGed20iRldAAxPcRgsJBoRELBJhv6n1AHy0DO08G01N4sEV28b8WW6QymRHXbdoKPL6AwfM3NTTXz5zk+XWqE/Gc9FSW9qCJSTs+T4RgRevOrUsn3vFSXsDA5Vlg0afQ3iN1f9Wk4jSPU7rN2mfBANCIh6LMLGuirXXvrssn1tvqrgPBVZIqLKHwUJ+aG0QzU3latU6ub6Kz528N+85bGbhrFtoAAAgAElEQVSuzMfm1mDV6rJP4vFoZJCzfaTMaEyyua03p40FVkg4rrux+olqq8avJqGFBAOhi+WO9gm6AzOVybrSszgeZCGRyjKxtjzmJhHh30/fDzDyaiISvP4h9si6cuSsPPKlE0lls0QiQjIeoSegdvpyh+bWJKK09aTY3NqTK6E+XtDmJgZqxZdrhRkGuvrSdPdnyp51DflJdU6132/KGd1kJxoRGqvj7A6I/ymTVfSns9z+/PrcNlWGOgLViWguqa42EWPl1o5A5kr0pbODSu2MBau225V3vVq+Dw0JWkgwUCu+HJVBw8KB33oAKH9CnfMzg6dJlC+6yUlzTYLd3Sk6+9K+d2778K+fZ9+r7uPh1wdMneVOko5Fhafe3MmX/vxKeT94DCilyGQVvanMmE1rdqxufeOxr8T4mRWHYDxqEhZxF8xNiZjdcR0sIdGTypQtusmJUdCxnwtufJaVWzvK5tsaDc++ZSS5dfdnqK+K0dGXLnt5b6v8+GMrt5f1c0fL6u2d/PD+lTy4YhtnHjSN6kSUX390EZThEj9gegPH7DUxFJ0Xy834mxUdbGjp5st/WQZ4IySyWVWWbN+xYJ8s3DA35WsSwTJF9KayrpibwNAktrT1lqUERrno7s/QWBOnoy9ddk3CcloHpfnSqf/9RO7xfcu38s59J3PM3pPK9vm1VTFaurq5c8lGDprZyH7T6sv22UEmGL+uj/znnctyqwN7bZpycdtlR+U9T5UjS2+MPP7Gjtxj1x3XAcqTUEqVNZnOSRCr/rZ09eXyddyinGadcnJ8GQUEGNGKK7d28KU/v8K7fvrkuDE9jXshEbFFINWOss7+UBy3zyQWzh5IVnNWm/Wa/nSWj90y0MQ+4kIEVlB9EpvNDmXu+STyHddBKG6YVQOZ/26RiEVYuqGV/3turavHGSnlXuk7fZaFClpWIuNeSNg7drllBvrZBw/LPfbbptnakx9940bGbCKg5qZjr30UcM880lybyMsbcHbp8wurhphbZLKK99zwDN/4e7AKHJa7/0OdI2vb2TulUhn3QqJ2lP1+R8IeE2r43nsPBgYS9/yizVFs0I0LPW5zXAexbIN75qb8FbvfCwKLRpc0if88Y3+AwIT9Oim3BmX5LK2KAu29wTItusWQ9hURmQV8EDgemAH0AMuBe4H7lFLBuAvGgFsThhPrwvJ74nCWLXfDrmrXJDoCWPDOrbh+Z5KV37+1hVs+iU+duBdZpfjRA6ty24JUBbfcwtFaUE6pT7KptYfOAF7bblBUkxCRW4DfAP3AD4CLgE8DDwNnAE+LyDu9GKSbeHUjWwlmfpsgrDLIVoE2N4SkPWKqszfNzU+9zcvrd5f9OCPBHtG1s9Odle8ezQ4h4eNvbQ9IaHLRce006fjtc7NTX+ZoRas3+JSGKgD+vnSz75YBLxjqW/yxUmp5ge3LgbtEJAHMdmdY3uFV7Rlrde336tLSJC46YjbTGpJcuGhW2Y9h1yTae9N8997XAXzNG7Cb1T5x/J6uHGNWc36JaT9/62Q8mjtnNx3XU+qr8p6nMtmCbWz9oNwaTZ8pEKxzvvfVLRwyq5H/d8JeZT1O0Bjq1zzTNDcVRCnVr5Ra7cKYPKXbND18//yDXT2OFfHj98rDKlveXBvno8fMza2Oykk8T0gEw25r9Xm49vyDmVhXNczeo8OplfmpSdhzQdwMgXV2cvR7EeQmVokZ+zkHLeTZDYYSEjOA50TkKRH5tIhM9mpQXtLdl+aYvSZy0ZHuKkXW6uqNbZ2uHmc4WrtTxCLiauJgNCJ865z5vPewmYGZNNrNm9ntnAG7icPPc49F7ELCvegmy/Ri4bc51U0uXLQH7z54Ol84dd/ctkkuLTiCRFEhoZT6IoY56SrgYGCZiNwvIh8VkYpJNezuz1DjQYSTtbr+D5/r3LT2pGisjrvuXPzYsXtyqKOZUaG2kF5hCYkGl4XEi1edyq8+sgjwV0ikbUmbDdXuLQgm1uYLoKAsCtygsTrODRcvZILtnKtcyt4PEkOeoTJ4Qin1KWAW8BPgC0AwGySMgp5UhmoXTC5O7HZaP9sgdvelPStk6OwGttXHMtqWucmqYOoWyXg0d95+Tpj2Y1tJoqceMLXsx3E2rQpK8uQzV57syXEqWShalDRbiMjBGKGwHwB2Al91c1Be0t2fpsaDMFh7tMmuzn5qJvhTNsvN2kVOnCYtP4VjW06T8G5B0Oej6cUeZZSMR3npG6d5UpssCJNmbSKa6znuNkE4X7cZKgR2HxH5hoi8Bvwe6AJOV0odrZT6mWcjdJnu/kxe1rVb2NX/nZ3+pfP3pctbQnko6h2r9s4+/xLrvPJJQDAi2dLZLB99xxxu+vDhTGtMMqE24VrU0QtfO4UfXXAI4J9Pwh7ifPHRc1w/3tJvngaMcyEB3A9UAR9QSh2ilPqeUuptj8blGT0e+SQWzm7OOcd3uRSnXwp96axnVTud5iY/ewRbUVZerKat79evSDalFKmMoqkmwekHTnP9eFMakkxrNCJ+/DpnS3P63Ml7c6WZCe4mTTUJIlLZjnqLoWaLfZRSVxXJlQBAgpJaOUo6elOks8qT1aWIcMXJRvN4PzUJN5vuOHHa//2sddPek6auKjbIhu4GucRJn1aZ1oTpZb6C39qTNVnXJWOeleJPxCLjXpN4VEQ+KyJ5saEikhCRk0XkVuCj7g7PXba1G5O1tQpyGysSZJePUT6+ahI+NpJv703RkPTGD+S/kDCOa5WC8QK/z9k6bsKDRYBFIhoJjKPeTYa6a84ALgVuF5E9gVYgCUSBB4GfKqVedn+I7rHdjLaZUu+NkEjGo9RXxXwtMeylJhGkqpltPSnXw18tcqtq30wvlpDwcMK0nPU+TZpb23rNcXjX2yIRi9KXzubu58n1lZkzUVRIKKV6gf8F/ldE4sAkoEcp1erV4NxmW4dxYU1t8O7HnViXGDeaRDwaIRmP0Gs2HvIzuqndSyHh96raByFR5UNtMqUU61u6mTOxlrOufwrw1sRWZZqbjrjmYcDfsjNuUtI3qpRKKaW2VJKA6E1lWL6pHRhcWsBNJtVVscsHn4RSir50xhASHmkSkB/h1OVndFNv2vUcCQtrcvZrVZ3zSXhqejGuqe6+tGfC8c6XNnHCjx7nObOfN3jsh4lFuPOljZ4dzy8qP12wANms4l0/fZJfP72G+qqYZ8llYGgSfjiuf/rwm+x31f3s7ur3tCex5ZeIRsTXdo+GJuGRT8JnJ+4Dy7cC+X093MaanK+861UO+86DnhxzyboWAF5c2zIwDg8FY9TnXvVeETghISJniMgqEVktIle6cYxIRDjO7H87b0qdG4coysS6Kl9CYG9/YT0A6azyzCcBA5rEhNoEXX6am3pTnmkSkYgQj4pvPonv3LMC8NbcZHeSd3kUoGClHm2zZfK39Xh3bwWp66KbBEpIiEgUuAE4E5gPXCQi89041qXH7cnMpmr+69wD3fj4okyqq6Klu9/z/sf2YGUvNQkromhibcK3ZLpHV26jozedV3PHbZKxqGvNjUrFD8e1l2TNBDq7kPCixI6F5WurdIp+oyLSARTqICIYZZ0aXBjPkcBqK2lPRP4InAesKPeB9ppc51l9FzuT6hIoBbu7U75FQ3hZlMxKXmuuSfhmbrr9hQ0kohEuPsq79ic1VVF6fAz5Bfc68BXCHyFh/LdC2X/ygQWcc8h0z47f6/Pv6xVDVYGtV0o1FPird0lAAMwENtiebzS3VQyTzdLCR1zzMM+/vWuYvcuHMKBKJD0ME6xPxkjEIjTXxnO9LLxmS1sPx+w90bU+EoWoTcQ8M7tYZLOKr961LPfcS5+Il74AC6sUR4sZLXjugpmetk7t1eamfERkiojMtv7cHFQJY7lcRBaLyOIdO3b4OZQRY++D/Msnvatykmdu8lCT2H9aA/tMqaOpJkFrt/cNWh5esY3lm9qZ3uhNwTeLmqqo52VINrX2cPsLxhpr3qRa3nuYd+srEfFcUFjmpp2dfdQnY547kp2tWu31oyqJYX9VETlXRN4E1gBPAGuB+1wazyZgD9vzWea2PJRSNymlFimlFk2eHK5eSLNsfZC9yvR24qUmcelxe3Lv545nQk2C1p4U2aw3N9KSdbt5eMU2Pv67xQDMbPL2u65JxDx31NsXAh9+xxxPSpDY8drkZF1KfemsJ6V1hqNS6ziV8qteDRwNvKGU2hM4BXjGpfG8COwjInuaPbQ/CNzt0rF8we48nepRpjeAfY3lR6OUppo4mayio9ebifN9Nz6bExDgrUMTjHLVXpchsedleFG00on3QmJgweFV5NpQuO3IfnVjm+cBL1CakEgppXYBERGJKKUeAw51YzBKqTRwBfAA8Dpwh1LqNTeO5Rd2m6mXCz37cb3UJCyaawzhuNsnv8SiOc2eHq+mKkZnb5qfPPRGXvSNm/TZJikvw5wt/DI3gTcl4Iux71QjjN7NkNhVWzs45+dPc92Db7h2jGKU8qu2ikgd8CTwexH5GeDaclAp9U+l1L5Kqb2UUte4dRw/2X+a0f21P+OdDdN+ATsL73lBc61xE/shJL78rv1Y4Gil6ja1iShv7+ziZ4+8yYW/eM6TY9p/4xqPNSfIT97LeGBW7E/7KyTONiOpPnH8PCBfSJcba6Hx6ibvi16UIiTOA3qAL2L0mHgLOMfNQVU6937ueKIR8TT6xG7mOWSWtxMmGPX3AV+c117VbLJjn6TXt3R74tS0mzt8MTfZNIm9vvZP14/Xkxq4pv0QEtd/8DDevObMnNbmZsixpTW196T5xt+WexrePOxyQynVZXt6q4tjGTdEI0IyFvGsQUs6k82zV3vRic+JZW5q8aG4oVclwu3UVuV/x72prOvfu12T8OM3dlZgzWaVq70d7HkojTXeC4lIRIggOSHhZq0ua43x6qY2Xt3UxgHTG/iQR3k/pUQ3nS8ib4pIm4i0i0iHiLR7MbhKxsuGJZYWcfL+U7jns8d5ckwnU8zEwe0+lEn3w7zmNPdYPbbdJG8h4ItPIl8guB3t02PTnPxYCFhYFQzcXN07v8s3t3d4tsgsxdz0Q+BcpVSjB8l044Z41DtNwvIDnLtgBgfNbPTkmE5qq2LUV8U8c+Lacfba9oJax0q+1YOaQvZJyg9zkzORzW0hYT/fZg9LrjgZMDe5d77OMvu3PLOW7/yj7IUoClKKkNimlHrd9ZGMMxKxiGdx1ZaQ8PNGApjamGRLW4/nx/VFk3BUFm7zwBfjt0nRmezstqZsNzdN87Dcv5Nk3CoN754mUSic+pm3drp2PDulCInFIvInEbnIND2dLyLnuz6yCicR9c7c1NJlTFATavwVEtMbk2xtd9/cdM29+SssPzSJOqeQcNHctHZnF3e8uCFPSPgRAhtxSImn3nS3GkKPTZPwKzEVCmsS3777Ne54cUOxt4yYQnXAvMovL0VINADdwOkYUU3nAGe7OajxQMJDx/XuLkuT8DfhaGpDkm1t7pubfvXUmrznzgnbC5zRNm4KifNueIav3LmMHtMkcePFC31JLnNOWl/80ys8vmq7a8ezCwmvy67Ysfw/9gz7u1/ZzFOry7fSL9Swy6s6VaVEN33Mi4GMN+JeahKWuclnTWJKfRU7OvtQSnlaiK3ShYT12db/Uw6Y6tqxRopbgQqZrMq7f5p9iG7KHds041qLsUxW0drdT38ZzU/dKf96sQx794jI9QU2twGLlVJ/L/+QxgeGJuFNMt3u7n4SsYgvzkw7tVUx4+bOZKlyKevbmY9QV+V94TcwypBYiHgT3dTWk0IkvwGQlzjNTeDeWHockUReLjqc1CaiVMUiud717T0psqq8Ppmgm5uSGGU43jT/DgEmAJeJyE9dHFtFE496l0y3u6ufCTUJX28kGFDLb35qjWsZuc5YdT+c1pCvSTRWxz3JNG/rSZOMRf37nQscNhZxp1SHNWmeceA0/ueiw1w5RqmIiNm73viNrd+6nIEpfvaHL+UO2hs42ayrhIjcCDwInAa86uLYKppELEq7B6tLMBocNfmojltYETc/emAV0xuTnL9wVtmP4SyN4JeQsJu4pjdWs2m3+1Fdrd39vhRvtCiksMVc0uKs8NdTDpjCOQtmuHKMkTChNsGurj5+/fQaHl6xDSizJlHA3OTVWqCUO2gmUIthYsJ8PEMplRER7zOjKoSEh5pEh4f9nYfCnuDlVjVYpxnCD38E5Js/5kyo4Y3tHa4fs70n5WlrWidSQJVwy9Rn/c5+hPoWYmJdgl2d/Vx9z0BkXTnvb68rCtspNZluqYjcIiK/BV4GrhORWuBhNwdXyXgZ3dTek6ah2r+MVAsvwjKdQsKP8FcncybWsLGlx/Wid609KV9CXy0KrWzdOmPL3ORHZnkhJtZWsaszf81czjIdhXwSXgmOYYWEUurXwDHA34C/AscppW5WSnUppb7s9gArlXjUu2S69t5UICbLpAemEOfN5Je5yc7siTX0Z7J5rUXdYN2ubl8nTUtIXPXuA3Lb0i4FZwRNk5hUl2BnZ77fqZyaRKEFpe9CQkT2N/8vBKZj9J7eAEwzt2nGQDwaIeVh7SY/a9tY2CewOxZvYGdn+a2Vzr7DfgrHb50zn6vefQBH7TkBgHuXbXH9mBcfPcf1YxTDMjfFbdVg01l3rvGgaRJTGpKDFn3l1CQKRUJ2etQed6iZ49+By4EfF3hNASe7MqJxgldlOZRSdAREk7Cv+l7b3M4X/7SU/7vsqLIeo9exuvJTOH7s2D1zjy86cg8eft29xDKLk/bzr52vpUnEbGGvbmkSf33Z6GocFE2iUFmQct7fhbSS/nSWVCabJ5TdoOgdpJS63Px/kqsjGKd4VZajqz9DVhEIn4Rz1efGSmiwT8L/8wbDgd7pQevWJh8TJi1nfTFN4qX1u9lnSt2YFyxvbuvg7lc2A8HRJKY1Vg3aVm5z05T6KrZ39NGQjPGrjyzimbd25XXnc4uhzE1HiMg02/OPiMjfReR6EZng+sgqHK+S6ZZtMDpZBUGTcDpV3RiTU0j40WCpEHVVcXpSmbL3KHYmDzqrz3qJpT/Ymw9Z13h3f5rz//dZPnXbS2M+jt8l0QsxrUBZkHIKif5MlkVzjRa83f0Zjpo3kX8/bV/XklLtDLXM+iVwKoCIvBO4FvgsRmLdTcAFro+ugolHhb50hkxWuZoR/KGbnweC0SjeaRpwY5VvFVn75tnz+dixc31PILSoM8+1qy9DY035zANOu7ef53vc3pN44o0dzJtcm9tmCUVLWCzdMLb2m4+u3JYrWAmQDIi5yeqXYqfc5qaGZJzvvucg5s/wtlPDUHdpVCnVYj7+AHCTUupO4E4RWer+0CqbA2c0klXw2MrtnDrf/Vo7fpSmcOJc9bkhuF7bbKTznLNgRmAEBEC9ma/R0Zcqaxc1L9tYDsfHj9+Tsw6ZzlTbhJk2w34tYTFW88ilv12c9zwomkQ8GmFGYxIRYVOrkTiZySrSmSyxUfgM7li8ga/8ZRmLrzqVSXVVOd/Dv/kQmDDU6KMiYgmRU4BHba8Fw9AbYk6fP5XG6jiPrNzmyfHmT/e/T5TT3FRXVd4bfFt7L7c8sxYIjkPTwtIkyu2H8TPJyomIMLOpOm9StISEpUmUO1fEbaftSHjqP0/mN5cckbdttNrEX5ZsBOCNrUYSZiqjSPiUKDnUZH878ISI7AR6gKcARGRvBrKvNaMkFo0woTZBp4s1WbLmDfn5U/Zh9sQa145TKk5tptw+tw0t3bnHSR8zjwthmdbK7bxu7/WmtMtoGTA3Gf/H8ps7BcySq04d/Ye5QDQigzSb/nSW0cQSWFF597+2lefXtNCfdj+KqRhDRTddIyKPYORIPKgGPGQRDN+EZoxUx6MFMynLhZUz4GcW7lCky7iq7OpL88MHVgHwrgOnjkrFd5O6nLmpvEKi1YOOd2PhoRXb+Mgxc3Mr6rGYm5wJZXUBiVyzM3tiDTdevJB1Ld1ce9/KUTuvraCO3z23LrfN2UPcK4a8k5RS/1JK/VUp1WXb9oZSauwhChqqE9GChbvKheXErfax6JuTZDzC7AmGVlPOsiQ3Pfk2L6wxXGg/unBB2T63XFiaRLlrVllC4si5E/jZBw8t62ePhQWzjF7qr2xs49hrH8391uUSEolYxJPIntFw5sHTmWj2mBhtQl2h/B6/NIngzB7jENc1iVTwNImVV5/Jk185iakNVWVNtLL7IOp9Kuo3FHVVxsqwo8zmIauS8H9/YAHnHTqzrJ89Fv5+xXG5xx29adp7DOE4FuXRHjLud2+U4bD8B6P1STh7pNs/02u0kPARQ5NwL6EuaPVt7MQiEVJlLNlgr34apKgmC+s3KMeiYEtbD3OvvJfHV23PdR30M4muFDr7xi4c7TkmXpW0GS3W9egsXV8q2QLSNHA+CY37GJqEm+YmY0IKoloej0pZNQlLIH71zP3L9pnlxCpuWI6QVcusdsktLwKGw9TPJLpSKIeZzb4q7wpQVFchxqpJFHpfXGsS44/qeHRQhnA56Q2yJhGNlLX4W09/BhG4/J3zyvaZ5SQRjSBSnqJvTrN+U3U8kNqTnXIICcvctO/UOr5x9vwxf56bWAuzPtv9va29l2vvW1lQS3BSyF9XpX0S44/qhOGTeGNbhyu9JSzHddDCQcHoWFbOsiQ9/Rmq4z627hwGESEZi/L6lna2d/SO6bOczt9yJue5RXmEhHE9f/6UfbnsuD2H2dtfrPa19t7mX/7LMn7xxFu8uLal2NtypNIFzE2xAEY3adylOhGlvTfN6T95kj8v3lj2z8+VUw6kJiFlrWPUncoEJvu2GMl4hIdf384x33+UpRtaR51Y51yINlUHX0iUwydhhZPGfQoFHQnNZnTT5f+3hDte3ABAvxmSnikhwiuVyeb1SQcd3TQusU9q63Z1DbHn6AhynkQsEilrnkRvfyaQwtCO9Tuks4r33PAMn7ptSUnva+tO8agtM3+QJhECIVFOTSJIWdbFmGALJLDyd6x+G6VEAfdnskysS/DzDx2W25bQQmL8YQ/jcyMpytIkkuPEcR18TSJ/fMs2lla44Et/Xsqlv13MZrMmkLPya9Ajm6A8meaWeTIMQsK+YKlOGOONmMMeTkh875+vc8+yLSSi+bkg2nE9DqmyTRq7utzo0mb6JBLB+5kNTaK8jeIDHzvvmNxKLbq4udXwYewy22M6FbBQaBJlyDRPZ8JjbrIjCFf97VVbrsjQUuKmJ98GDGFoz43QmsQ4xB75sKurf4g9R4fVpS2Q5qZomR3XqUwgz9OOc3KIlOhkt8pPdJh2facvJxRCYogkwt5Uhj++sH6QhuTECgv1a0U9Wta3dHPbv9bz6iZDcyx1cRSPSp5g0Ml04xC7ianFDSGRCrK5qfwhsEH3STgdlqUuDK0SDVZ2tTOMtikE0U12J70zku+6B1Zx5V2v8tCKoSsiW4sKv1bU5aLUBLtoRPIEg3Zcj0MOn2N0mjpkVmPOlFBO2ntTJOMR31YgQxGLlN8nEXRzkzM+PlqiJmEVe9vdXVhI1AWwDIkTu+P623e/xpHXPJx7bi2Q7OGihQiT4xrgHfMmFtxeaq5MOqvyKgn4ZWbz5NsWg+tFZLWILBORhUX2e1xEVonIUvNvihfj84uT9p/Cq98+ndPnT6WzL83Z//MUW9vGFkNvp6UrlRdlESTi0UhZc0N6+oNvbnJqEpESfRKWELAm0z5HAmYYJk274/r3z69ne8eAD876Hoaz1adC5pO47eNHcckxcwdt70uXlkCbdvSQqHSfxJnAPubf5cCNQ+x7sVLqUPNvuyej85H6ZDw3CSzf1M6tz60t22e3dPUxoS6YQiIWFdJZRTarhrVFD8Xurn6OvfZRNrX2BF6TyGSc5qbSJjtrv92WkHCsRGMhmDQLhcBav7ulURVaM7y2uY37l28F7HkSwReKYPxukwrcf6VqEqlMNk8wNPjke/Lq2z4P+J0y+BfQJCLTPTp24LFXfCzn7d7SnaI5oJpELBIhnVFcduuLnHjd46P+nKdW78y1i6xJBNvsMsgnUaK5yVpBW8X8nJPMwTMbyzA6dylUi8iqCBA1hVyhJLN3X/80nzTzScIUAmtRX6BF71A+iXN//nTucSqTzdMk/LqXvfq2ZwIbbM83mtsKcYtpavqGBLXGQpmxr4DLecYtXX25uvZBIx4V2ntSPLZqB+t2dQ//hiLY7fxBj/JxzpOlmpss3421GrcXCfzT5UczZ2JteQZYZj55wl6cs2AGsSLn2WUWt7SEpdNn4yxfEjZzExSOSLLMTb2pDOf/7zMs3dCae82eO+P0SejoJoOLlVIHA8ebfx8utJOIXC4ii0Vk8Y4dOzwdoBvkCYky6BLfvWcFj6/azu6uVK48QNCIRSUvdn60Jie7X6NQo5Yg4bS5l6xJmFFglnCwaxJBDEqwuPLM/fmfiw4rmlnfbbbutcxpzvakq8z+zhapEIbAFvIjWL/fyq0dvLS+lW/+fXnB9zp9En7h2l0lIp8BPmE+fRHYw/byLGCT8z1KqU3m/w4R+QNwJPC7AvvdBNwEsGjRojJ3Svae6rjN3DRGGbF6ewc3P72Gm59eAxBYTSIWyb/4jeikkV+O9ogYv2y2peKcBEvVJCwzS18qy9wr7817LUymFyeWJmHliziF6A6bc1spFcoQ2EICzfKtWIuEdEbR1p3i0ltfzNvPaW7yC9dGoJS6wXJAA38DPmJGOR0NtCmlttj3F5GYiEwyH8eBs4HCIrbCqK2yaxJjw3LyWUysqxrjJ7qD02RgZaOOFHuuSdCFxHsPy7ewljrXWclz7QUS0qoCMImMlm7L3GSeglPjsAuJvnQ2dCGwUFyT2NLWw6f/YPhaMlnFzx97kyXrduft53Rc+4VXI/gn8DawGvgV8GnrBRFZaj6sAh4QkWXAUgxN41cejc9X7Oam/jHmDmxrz/7dDo0AABWoSURBVC/vcXSRWG2/iTku/kITYCns7h7ILwm6T+IbZ8/nD584Kve8dMe1cU20F8gjCMOE+ddPH8PMpmrqqmJ5EV2dprkpUsTcZBcSvakMqUyWiJQeFRYECgnxvnSGa+59nQ0tRsBFRile29w+aL90RgWi9L0nRlxlGJw/U+S1Q83/XcDhXownaFTbzCxj7VzWk8oYiWpZxazmavacFEynpuXMbKyO09aTKjgBlkKeJlEgkiRIRCPCHs01ueclO65Nn0ShZLMw2OcPm93MU185CRFYePVDuaTA7r58x7Uzb2Znp11IZOnPZEMhFO0UdFynsnmmtUxW5eWNWFgRYd86Zz5HzJ3g3iCHIdievnFCjS0JbKw9kHv6M8yeWMNdnzqmrLWRyo1VtO6k/Sbzt6Wbx4UmAfmCrFRNwopuKtSyMyyRPpZArEvGckLCqldmhb72O0J7d9iERHd/modXbAuEjX4kFBJqfeks9oo06WyWXZ2Dr//3HT4LgI8d62+DpXB94xVKjc0n8crG1jEJCqs8RVNNgsn1wfRHwMDkfvqB04DR9xt4a0dn7nFDdfDXPHW2CKxSNYmh+iQHwWY9EmptWvNVf1vOjo6+XJKhM/9jZ8fAAmDphlbe2tHF+YcVi5wPJsVCYO2aRFdfhnbH9f/Rd8zh6vMOcn18pRCuK6xCsd/oK7d28Jk/vDTqz+ruTwe+rwLAd847kKvPOzCnRo/G3LS1rTfPB1MVwEKGTuz29BfWtJTUynKoDn5hW1k7Fy7b2ntzDmtnuYqO3hQTzOg8y/T0LnNRERYKCfGeVCav3Huh4p4fO3bPwPhewnWFVShO59SjK0dejeTmp95m1dYOelLZPB9HUJnVXMOH3zE3t/ofrrhbIV5eb0SD3PChhfzu0iPLOj6vuPAXz9E2TMOpoTr4hc1GP6U+mfe8vTeV80U4M5E7+9K5EO6dZgHMuoDnwjhJFOhLvauzf8i8oOe+ejJzA+RLDNcVpilIOpPlu/e+zt+XbqKnP011PDw/a1UsSm0imrNTj4Qn3thBfVWM0+ZP5Z37TnZhdN6w4DsPst9V99HaXbgS8FC+pWLZzEFlSoOhScxqrgYMDdLyufSms3zm9y9xx+INKKUMIWHWPtppOnbDUPHWTiI6WLvd2dmXay1s55T9jXqmQfOthWc2GWcMt7q0Y9nz+9PZUSel+UlzbSJXvK5U+tNZHn59O+/cb3LoTC6F6EtnWb5pcBgkDI76sROEEMmRcNgeTQC851DDt9DWk8ppSvcv38K9r27h6ntW0JvKklUwyczzuetlI/c2dEKiwLXZ0tVfsF3x1e85iNe/c0bg7t/w310VwhNfPjHv+UjML1ZkUH8mG4qS2U4m1CZyxetK5a8vb2RnZx8XLJzl0qi8R1FYYxjKJxE2Tj9wGnd+6h184p3zACOJ0grxtTSmI+dOyDUpmuRIBg2fuWnwFJtVsHZn16DtE2oTgWycpYVEQJgzsZbrLlyQUzW7U6VH+1jZyv1pQ0gEvWS2k+aakWsSL67dzeT6Kk7cL3xmpilFos6KNWFKZdQgs9IVJ+3Nzz90WNnH5gWHz5lAfVWMiJiahOO8+zNZukwh4SwrE4agDDv2EOXvvucgvvyu/YDC4cxBXdxpIREgLjh8Fj/94KEAdI8gDDanSaSzdKcyobuRJo5Ck+hJZahPxkJnbgF4+EsnsMjsSmjHXvDQTjqbHbSCPnhWI2cfMsOV8XlBJCI0mImUTnNabyqT0yScZWXC9nvbNYl/O3oOR+3pX1LcaNFCImBYiXVPvbFzUOnkYlhN5tt70yhFIFXWoWiuTdDS2T+oLMNQ9PaHTxhaNCTjTG+qHrS9s0CuyG3/Wse29j7qHUKiNmB269HQWB2nvTc16HfvyRMSwSxQWSrOEFh7dFdzTZwzQhDSq4VEwKg1HXM/efgNfvHkWyW9xzI3PfGGETobtsmzJhGlqz/Df965rOT39KbDKySK0dmX4vz/fYbfPrMmt+2qvxk1Luuq8iNeghJDPxYaq+O0dqdIZRUHz2zkmvcexDF7TaSnP5MzNxXq7BYmnJrPtMYBIfH98w/h+ouCbzLUQiJg2LWApetbh9hzAMvclOvcFbJon0NmGREvf1mycdi+Equ3d/Bf/3iNrr5M6DQmO4W0xJauFC+tb+Xb/1gx6LV6R1RPJQiJ6Y1JNu7uJp3JUhWLcPFRc5jRVE17bzpX3K+xOs7XzzrA55GWD7v5aXJ9VSgi84I/wnGG3els1dsfDmdKf9jmj9PmT+Wa9xolCN4uEPVh59LfLuaWZ9ayZmdXYB19pZDODo5YspcYceI0N01tCG7JlVLZe0oda3d1G0UpTQdvdTzKjo4+rrzrVcDQoKxIqErDCmC48eKF3Pu543weTXHCb9isMGpsDYi6+kpzXttLWkyqS3DB4eELCz3cdOSu2NzOXpPriu5nOfT70uEL9bVTKKr1zW0djn0GtA17rZ9HvnRCYFuWjoR9ptSTySpWb+/kUDN/whmZ11RjmNmeufLk0CUODodVouTMg6f7PJKh0ZpEwLCbULqKRLs4sVdQPfWAqaGoYeRkeqPhyN3a1jvkflYkTG8qG6rMcifOLmwAa229vv+yZCN7fe2fuecttuSroYRomNh7inEeHb3pnPnMLvhv/sii3POZTdVMbUgO/pAQ8rFj5wLBDXl1Et67rEKx2yhLLVVhr6AaVjt9QzJGTSLKlmGEhL2cdJgd18NFcj3xRn7v9tH22wgydieu1c7Wun7PO3QGp86f6su43OZb5xzI2mvf7fcwSkabmwLMrq4+0pnsoC5uTuwTSFgnThFhWmOSbe2FhcQZP32S4/eZlFc2OxlSgQiDNYnpjck8AWn3QVTHo/zPRYeRVYo1w/hswkRzTYKIGBnIVtJZ0lwkhfU6LoalNYURLSQCjFJGnZcpw6jZdsd1mG+uaQ1JtrT1FHxt5dYOVm7Nt9mH+VztWcYXHj6LGU3V/OyRN3PbNrcOfA9Xv+cgDprZCAxEglUC0YgwobaKnZ19uYWQVccprBpxId747pmhCyaxo81NAadQW0MneZpEiG+uaY1J1u3qzvUVuGfZZt7Y1jGoz4BFmIVExqZJiDCozawV6RSPSiizdEvFyoOwnNJW+94w/7ZOErHIsNaAIBPekY8T7C0ci9Fhc1yHxRlWiHMOmcGurn5+9+w6MlnFFX94mXN//jS7uwrb48N8rvY8iemN1blIl2P2mgjAhpYeDpjewJvXnMUeE2oKfkYlYJ23JSSs6LVKEhJhRwuJAPLUV07iz598B0AuqagQLV393LlkY17Nn7AV97Nz0v5T2GtyLc+8tZOP3/oiYEQx7SwiKMM8kViaxCXHzOWKk/fm6HkT+Y/T9+WGDy1knqlVhPm3LBWryqu10j5/4UwSsQjnHhreulSVhvZJBJA9JtTkVlhDCYlLf/siSzfkZ2WHeeIEOHBGI3e/sjn3fHpjkl1FKsSG2XFtRTe957CZue5yV5y8DwD7Tq3n7Z1dof8tS2EPs/lQn2lm2ntKPW9890w/h6RxoIVEQEnGo9QnY0MKCaeAgPC1s3Ry4IyGPCExo6maXUU0iWQIShoUwxIS0QJVTZtrjQSyMPuXSuUT75zHzq7+UBS6G69oIRFgJtdXDSkkChGNhjiMAkOTsFMdjxZsFA8DxRDDiCUkIgXkXFON4cwdD5pEfTLO9957sN/D0AxBeJdi44DJdcWFhD2pDIwIGQhfz2Mn82c0AFCbiHLMXhPpTWXysrDt5xdmITGr2XBGFyr53WyWoiiUla3ReI0WEgFmcn1V0eim1p781bU12RQyX4SJCbUJpjcmmdlcTTIepTedYZMtZ+Cd+w50oqurCu9K+8fvX8CNFy9k7qTBNZgsTaIvXTltSzXhRQuJADOlPllUk+hwVH49ep4ROjm5SGvMMHHxUbN5z2EzScYjLN/Uzn3Lt+Zeswq+Qbg1icbqeNHCbk1mC1stJDRBQAuJADOxLkFnX5qv//XVQa85a/l8770H8bfPHMs+U+u9Gp5rXHHyPnz6xL1JFihUOKFmoAlNmIXEUFitSq2IH43GT7SQCDCWVvD759fnbU9nstz89Jq8bc21iVy55Uqhyua4taqEnrDfgLmpElp4FsKq4qs1CU0QqMy7rEI479AZ3LlkIy+sbaEvnaEqFmX9rm4uvfVFVm/Pb1AT9tDXQiRtpcDv+tQxzGyuziVfQWV0ZyuElUx30ZF7+DwSjUYLiUBTFYvyoaNm8/yaFt7c1slBMxu55dk1gwREpWKV3fjIO+awoMK0pKFork2EqpS0prKpvOVnhWEVfjv7f54GYPmmNj+H4ylVZrJcXYX6HjSaMKCFRMA5cEYjCdOU1J/O8trmdp9H5B1WEbwwdtrTaCoFLSQCTjQifOWM/QB4bXNbrkrmeKDPbDCUCHH5DY0m7Gg9PgTUmFE8z69pGfTaD953MBNqw58bUYi+lCEkqrSQ0Gh8QwuJEGCVjH5hTQvJeIRec/K893PHDap1VElYIaBV8Xwh8cP3HcKk+kSht2g0mjITGCEhIvsDtwALga8rpa7zeUiBwRISyze1MW9SHecvnMm8ybUVLSAAFs5u4vYX1nPA9Ia87e8/QoeGajReERghAbQAnwPe4/dAgoZlbtrZ2cfcSbV8/Ph5Po/IGy44fBbv2GtirhieRqPxnsAYe5VS25VSLwKFe1WOY2rMQnZZNT66lVmIiBYQGo3PBEZIaIpjFwzjSUhoNBr/CaWQEJHLRWSxiCzesWOH38NxHXuNouQ4aESj0WiCg69CQkQ+IyJLzb+SO58rpW5SSi1SSi2aPHny8G8IOdVak9BoND7hq+NaKXUDcIOfYwgDdk1iPLS01Gg0wSEw0U0iMg1YDDQAWRH5AjBfKTV+6lAUwV4NtbpCy2NrNJpgEpgZRym1FZjl9ziCiIggAmqcRTdpNBr/CaXjejxi9YvQ5iaNRuMlWkiEhIak0fe4WmsSGo3GQ7SQCAkN1YZlUJubNBqNl2ghERIaq01NQpubNBqNh2ghERIsIWH24dFoNBpP0EIiJEytTwLQlx4/TYc0Go3/BCYEVjM0XzvrABpr4pw+f5rfQ9FoNOMILSRCQmNNnK+ddYDfw9BoNOMMbW7SaDQaTVG0kNBoNBpNUbSQ0Gg0Gk1RtJDQaDQaTVG0kNBoNBpNUbSQ0Gg0Gk1RtJDQaDQaTVG0kNBoNBpNUUSpcBcDEpEdwLpRvn0SsLOMwwkD+pzHB/qcxwdjOec5SqnJw+0UeiExFkRksVJqkd/j8BJ9zuMDfc7jAy/OWZubNBqNRlMULSQ0Go1GU5TxLiRu8nsAPqDPeXygz3l84Po5j2ufhEaj0WiGZrxrEhqNRqMZAi0kNBqNRlOUcSkkROQMEVklIqtF5Eq/x1NOROQ3IrJdRJbbtk0QkYdE5E3zf7O5XUTkevN7WCYiC/0b+egQkT1E5DERWSEir4nI583tlXzOSRF5QUReMc/5v8zte4rI8+a5/UlEEub2KvP5avP1uX6OfyyISFREXhaRe8znFX3OIrJWRF4VkaUistjc5um1Pe6EhIhEgRuAM4H5wEUiMt/fUZWV3wJnOLZdCTyilNoHeMR8DsZ3sI/5dzlwo0djLCdp4EtKqfnA0cBnzN+zks+5DzhZKbUAOBQ4Q0SOBn4A/EQptTewG7jM3P8yYLe5/SfmfmHl88Drtufj4ZxPUkodasuH8PbaVkqNqz/gHcADtudfBb7q97jKfI5zgeW256uA6ebj6cAq8/EvgYsK7RfWP+DvwGnj5ZyBGuAl4CiMzNuYuT13nQMPAO8wH8fM/cTvsY/iXGdhTIonA/cAMg7OeS0wybHN02t73GkSwExgg+35RnNbJTNVKbXFfLwVmGo+rqjvwjQpHAY8T4Wfs2l2WQpsBx4C3gJalVJpcxf7eeXO2Xy9DZjo7YjLwk+BrwBZ8/lEKv+cFfCgiCwRkcvNbZ5e27GxfoAmXCillIhUXNyziNQBdwJfUEq1i0jutUo8Z6VUBjhURJqAvwL7+zwkVxGRs4HtSqklInKi3+PxkOOUUptEZArwkIistL/oxbU9HjWJTcAetuezzG2VzDYRmQ5g/t9ubq+I70JE4hgC4vdKqbvMzRV9zhZKqVbgMQxTS5OIWAs/+3nlztl8vRHY5fFQx8qxwLkishb4I4bJ6WdU9jmjlNpk/t+OsRg4Eo+v7fEoJF4E9jGjIhLAB4G7fR6T29wNfNR8/FEMu721/SNmVMTRQJtNjQ0FYqgMvwZeV0r9t+2lSj7nyaYGgYhUY/hgXscQFheYuznP2fouLgAeVabROiwopb6qlJqllJqLcc8+qpS6mAo+ZxGpFZF66zFwOrAcr69tvx0zPjmDzgLewLDjft3v8ZT53G4HtgApDJvkZRi22EeAN4GHgQnmvoIR6fUW8CqwyO/xj+J8j8Ow2y4Dlpp/Z1X4OR8CvGye83Lgm+b2ecALwGrgz0CVuT1pPl9tvj7P73MY4/mfCNxT6edsntsr5t9r1lzl9bWty3JoNBqNpijj0dyk0Wg0mv/f3v2DRhFEcRz//rQTYxoF7YRICiXRQAxiEBTtUohaSiobiyjGXkiRQiSNlY0KglXELmhIIymsYqMHUQTBWktDLhK9Z7Fz3JpkLn/uEsT8PnDc7t3s292D47Ezu/M2yEnCzMyynCTMzCzLScLMzLKcJMzMLMtPXNuuJKl+GyHAYeA38D2tL0bE2W3YZx8wEhE31m3cPM4IxTE+bc+RmeX5Fljb9SSNAQsRMbHN+3kBjEfE+xbj7APeRkRfe47MLM/dTWYrSFpI7+clzUqalPRZ0n1J11Mth4qkrtTukKSXkubSa3CNmB1Abz1BSBqT9EzSTKoZcFXSgxR3Ok01QtrnfKoPMAEQEYvAV0kDO/Wb2O7lJGHW3EmKGgY9wDDQHREDwGPgVmrzkKKmwWngWvpupX6Kp6PLuoAh4DLwHHgTET1AFRhKXWJXgBMR0QuMl7Z9B5xr/fTMmvOYhFlzc5Hmv5H0BZhJn1eAC2n5EnC8NPPsAUn7I2KhFOcIjTGPutcRsSypAuwFpkuxj1LUTFgCnqioxDZV2vYb//nMr/ZvcJIwa+5nablWWq/R+P/sAc5ExFKTOFWK+YRWxY6ImqTlaAwQ1igK6fxKXUoXKSa1G6GY/ZQUq7qF8zHbFHc3mbVuhkbXE5JOrdHmI3BsM0FTjYzOiHgF3KEoVVrXzeruK7O2c5Iwa91toD8NLs8DN1c2iIhPQGd96ucN6gCmJH0AZoHR0neDFBXpzLaVb4E12yGSRoEfEbHWwPZm4vQBdyNiuD1HZpbnKwmznfOIv8c4tuogcK8NcczW5SsJMzPL8pWEmZllOUmYmVmWk4SZmWU5SZiZWZaThJmZZf0BPCSLS4vKs6UAAAAASUVORK5CYII=\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -201,7 +201,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 69\n" + "Starting experimental run with id: 102\n" ] } ], @@ -221,9 +221,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -243,14 +243,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 71\n" + "Starting experimental run with id: 103\n" ] } ], @@ -258,6 +258,8 @@ "freqmeas = Measurement()\n", "freqmeas.register_parameter(osc.periodogram)\n", "\n", + "osc.dt(0.01)\n", + "\n", "with freqmeas.run() as datasaver:\n", " datasaver.add_result((osc.periodogram, osc.periodogram.get()))\n", " \n", @@ -271,9 +273,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -281,39 +283,56 @@ } ], "source": [ - "_ = plot_by_id(dataid)" + "axs, cbax = plot_by_id(dataid)\n", + "aa = axs[0]\n", + "aa.set_yscale('log')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just for the fun of it, let's make a measurement with the averaged periodogram." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 72\n" + "Starting experimental run with id: 104\n" ] } ], "source": [ + "no_of_avgs = 100\n", + "\n", "with freqmeas.run() as datasaver:\n", - " datasaver.add_result((osc.periodogram, np.log10(osc.periodogram.get())))\n", " \n", + " temp_per = osc.periodogram()\n", + " \n", + " for _ in range(no_of_avgs-1):\n", + " temp_per += osc.periodogram()\n", + " \n", + " datasaver.add_result((osc.periodogram, temp_per/no_of_avgs))\n", + "\n", "dataid = datasaver.run_id" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -321,7 +340,9 @@ } ], "source": [ - "_ = plot_by_id(dataid)" + "axs, cbax = plot_by_id(dataid)\n", + "aa = axs[0]\n", + "aa.set_yscale('log')" ] }, { @@ -333,42 +354,44 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 77\n" + "Starting experimental run with id: 105\n" ] } ], "source": [ "meas = Measurement()\n", - "meas.register_parameter(osc.dt)\n", - "meas.register_parameter(osc.time_axis, setpoints=[osc.dt])\n", + "meas.register_parameter(osc.npts)\n", + "meas.register_parameter(osc.trace, setpoints=[osc.npts])\n", "\n", "with meas.run() as datasaver:\n", "\n", - " for dt in [0.01, 0.02, 0.03]:\n", - " osc.dt(dt)\n", - " datasaver.add_result((osc.time_axis, osc.time_axis.get()),\n", - " (osc.dt, osc.dt.get()))\n", + " osc.dt(0.001)\n", + " \n", + " for npts in [200, 400, 600, 800, 1000, 1200]:\n", + " osc.npts(npts)\n", + " datasaver.add_result((osc.trace, osc.trace()),\n", + " (osc.npts, osc.npts()))\n", " \n", "dataid = datasaver.run_id" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, From fb6b62e0248acb938351851a7f26cd77c60ce80b Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 25 Sep 2018 09:33:23 +0200 Subject: [PATCH 101/719] If to elif --- qcodes/dataset/measurements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 78d7d68fc60..a1c2242b013 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -156,7 +156,7 @@ def add_result(self, *res_tuple: res_type) -> None: self._unbundle_arrayparameter(parameter, res, found_parameters) - if isinstance(parameter, ArrayParameter2): + elif isinstance(parameter, ArrayParameter2): self._unbundle_arrayparameter2(parameter, res, found_parameters) @@ -653,7 +653,7 @@ def register_parameter( setpoints, basis, paramtype) - if isinstance(parameter, ArrayParameter2): + elif isinstance(parameter, ArrayParameter2): self._register_arrayparameter2(parameter, setpoints, basis, From 0aa26b26414407a4d444dd29eb8eebb89754bd68 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 10:17:53 +0200 Subject: [PATCH 102/719] First attempt of porting SignalHound driver --- .../signal_hound/USB_SA124B.py | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 01f24221d51..ce41b97323a 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -5,13 +5,15 @@ from enum import IntEnum from typing import Dict, Union, Optional, Any, Tuple -from qcodes import Instrument, ArrayParameter, Parameter, validators as vals +from qcodes.instrument.base import Instrument +import qcodes.utils.validators as vals +from qcodes.instrument.parameter import Parameter, ArrayParameter, \ + ArrayParameter2 log = logging.getLogger(__name__) number = Union[int, float] - class TraceParameter(Parameter): """ A parameter that used a flag on the instrument to keeps track of if it's @@ -317,6 +319,25 @@ def __init__(self, name, dll_path=None, **kwargs): vals=vals.Enum('log-scale', 'lin-scale', 'log-full-scale', 'lin-full-scale'), parameter_class=ScaleParameter) + + self.add_parameter('frequency_axis', + label='Frequency', + unit='Hz', + get_cmd=self._get_freq_axis, + set_cmd=False, + vals=vals.Arrays(), + snapshot_value=False + ) + self.add_parameter('freq_sweep', + label='Power', + unit='depends on mode', + get_cmd=self._get_averaged_sweep_data, + set_cmd=False, + parameter_class=ArrayParameter2, + vals=vals.Arrays(), + setpoints=(self.frequency_axis,), + snapshot_value=False) + self.openDevice() self.configure() @@ -657,6 +678,12 @@ def get_idn(self) -> Dict[str, Optional[str]]: output['firmware'] = fw_version.value.decode('ascii') return output + def _get_freq_axis(self) -> np.ndarray: + sweep_len, start_freq, stepsize = self.QuerySweep() + end_freq = start_freq + stepsize*(sweep_len-1) + freq_points = np.linspace(start_freq, end_freq, sweep_len) + return freq_points + class Constants: """ From 35d9bd868b4ec036222b69de1fc9215fe1d129da Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Sep 2018 15:23:33 +0200 Subject: [PATCH 103/719] example of new signal hound --- ...example with SignalHound USB-SA124B.ipynb | 371 ++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb diff --git a/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb b/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb new file mode 100644 index 00000000000..92fcc566e14 --- /dev/null +++ b/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import qcodes as qc" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument_drivers.signal_hound.USB_SA124B import SignalHound_USB_SA124B\n", + "from qcodes.dataset.measurements import Measurement\n", + "from qcodes.dataset.plotting import plot_by_id" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initialized SignalHound in 6.08s\n" + ] + } + ], + "source": [ + "mysa = SignalHound_USB_SA124B('mysa', dll_path='C:\\\\Program Files\\\\Signal Hound\\\\Spike\\\\sa_api.dll')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'vendor': 'Signal Hound',\n", + " 'model': 'sa124B',\n", + " 'serial': 17172185,\n", + " 'firmware': 'Version 3.13'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mysa.get_idn()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-93.19955444, -91.95262146, -91.95391083, ..., -93.46353912,\n", + " -92.25684357, -91.50266266])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mysa.freq_sweep()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "mysa.frequency(2e9)\n", + "mysa.span(0.5e6)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 638\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.n_avg(1)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "mysa.prepare_for_measurement()\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 639\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.n_avg(10)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "mysa.prepare_for_measurement()\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 640\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.n_avg(100)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "mysa.prepare_for_measurement()\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 641\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.frequency(3e9)\n", + "mysa.span(1e6)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "mysa.prepare_for_measurement()\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning: saBandwidthClamped\n", + "Starting experimental run with id: 642\n", + "Warning: saBandwidthClamped\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.frequency(3e9)\n", + "mysa.span(1e8)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "mysa.prepare_for_measurement()\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "mysa.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 82a4e8532b443802968b7a4f2d7efb2dafec4df3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 10:55:54 +0200 Subject: [PATCH 104/719] Add a typecheck to make mypy happy --- qcodes/dataset/measurements.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index a1c2242b013..ae8d6e4e3d7 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -765,6 +765,10 @@ def _register_arrayparameter2(self, name = str(parameter) my_setpoints = list(setpoints) if setpoints else [] for i, setpoints in enumerate(parameter.setpoints): + if not isinstance(setpoints, Parameter): + raise RuntimeError("The setpoints of a " + "ParameterWithSetpoints " + "must be a Parameter") spname = setpoints.full_name splabel = setpoints.label spunit = setpoints.unit From 308af2d8256d75cc9efd644c63f1ab1576b572df Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 13:37:48 +0200 Subject: [PATCH 105/719] rename driver example notebook --- ...example with SignalHound USB-SA124B.ipynb | 371 ------------------ ...ound USB-SA124B new Array Parameter.ipynb | 370 +++++++++++++++++ 2 files changed, 370 insertions(+), 371 deletions(-) delete mode 100644 docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb create mode 100644 docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb diff --git a/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb b/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb deleted file mode 100644 index 92fcc566e14..00000000000 --- a/docs/examples/driver_examples/QCoDeS example with SignalHound USB-SA124B.ipynb +++ /dev/null @@ -1,371 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import qcodes as qc" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.instrument_drivers.signal_hound.USB_SA124B import SignalHound_USB_SA124B\n", - "from qcodes.dataset.measurements import Measurement\n", - "from qcodes.dataset.plotting import plot_by_id" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initialized SignalHound in 6.08s\n" - ] - } - ], - "source": [ - "mysa = SignalHound_USB_SA124B('mysa', dll_path='C:\\\\Program Files\\\\Signal Hound\\\\Spike\\\\sa_api.dll')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'vendor': 'Signal Hound',\n", - " 'model': 'sa124B',\n", - " 'serial': 17172185,\n", - " 'firmware': 'Version 3.13'}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mysa.get_idn()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-93.19955444, -91.95262146, -91.95391083, ..., -93.46353912,\n", - " -92.25684357, -91.50266266])" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mysa.freq_sweep()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "mysa.frequency(2e9)\n", - "mysa.span(0.5e6)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 638\n" - ] - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "mysa.n_avg(1)\n", - "meas = Measurement()\n", - "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", - "mysa.prepare_for_measurement()\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting\n", - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 639\n" - ] - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "mysa.n_avg(10)\n", - "meas = Measurement()\n", - "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", - "mysa.prepare_for_measurement()\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting\n", - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 640\n" - ] - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "mysa.n_avg(100)\n", - "meas = Measurement()\n", - "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", - "mysa.prepare_for_measurement()\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting\n", - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 641\n" - ] - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "mysa.frequency(3e9)\n", - "mysa.span(1e6)\n", - "meas = Measurement()\n", - "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", - "mysa.prepare_for_measurement()\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting\n", - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Warning: saBandwidthClamped\n", - "Starting experimental run with id: 642\n", - "Warning: saBandwidthClamped\n" - ] - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "mysa.frequency(3e9)\n", - "mysa.span(1e8)\n", - "meas = Measurement()\n", - "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", - "mysa.prepare_for_measurement()\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting\n", - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "mysa.close()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.6" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb new file mode 100644 index 00000000000..2e7b30d6726 --- /dev/null +++ b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb @@ -0,0 +1,370 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import qcodes as qc" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument_drivers.signal_hound.USB_SA124B import SignalHound_USB_SA124B\n", + "from qcodes.dataset.measurements import Measurement\n", + "from qcodes.dataset.plotting import plot_by_id" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: Signal Hound sa124B (serial:17172185, firmware:Version 3.13) in 6.15s\n" + ] + } + ], + "source": [ + "mysa = SignalHound_USB_SA124B('mysa', dll_path='C:\\\\Program Files\\\\Signal Hound\\\\Spike\\\\sa_api.dll')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'vendor': 'Signal Hound',\n", + " 'model': 'sa124B',\n", + " 'serial': '17172185',\n", + " 'firmware': 'Version 3.13'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mysa.get_idn()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-95.04801941, -90.23478699, -90.57860565, ..., -92.38912201,\n", + " -99.49388123, -96.53659058])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mysa.freq_sweep()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "mysa.frequency(2e9)\n", + "mysa.span(0.5e6)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 928\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.avg(1)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 929\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.avg(10)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 930\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.avg(100)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 932\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.frequency(3e9)\n", + "mysa.span(1e6)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 934\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "During call of saInitiate the followingWarning: saBandwidthClamped was raised\n" + ] + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mysa.frequency(3e9)\n", + "mysa.span(1e8)\n", + "meas = Measurement()\n", + "meas.register_parameter(mysa.freq_sweep) # register the first independent parameter\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((mysa.freq_sweep, mysa.freq_sweep.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting\n", + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "mysa.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From c78aff5ebb93be14ccbc3badd639cad93cfc2c25 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 13:38:50 +0200 Subject: [PATCH 106/719] move once again --- ...xample with Signal Hound USB-SA124B new Array Parameter.ipynb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/examples/driver_examples/{Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb => Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb} (100%) diff --git a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb similarity index 100% rename from docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb rename to docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb From ac9f7625fc4d9b368ab86d84b51744a3c46e1151 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 13:47:45 +0200 Subject: [PATCH 107/719] Make sure that data is synced before acq --- qcodes/instrument_drivers/signal_hound/USB_SA124B.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index ce41b97323a..a83a6adc711 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -604,7 +604,10 @@ def _get_averaged_sweep_data(self) -> np.ndarray: Averages over SH.sweep Navg times """ + if not self._parameters_synced: + self.sync_parameters() sweep_len, _, _ = self.QuerySweep() + print(sweep_len) data = np.zeros(sweep_len) Navg = self.avg() for i in range(Navg): From 3a39607ac87c6e074a041139a2a6386c705f8d66 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 14:37:49 +0200 Subject: [PATCH 108/719] Reneame new array parameter --- ...arameter Example with Dual Setpoints.ipynb | 72 ++++-- ...Simple Example of new ArrayParameter.ipynb | 241 +++++++++--------- ...Hound USB-SA124B new Array Parameter.ipynb | 74 +++--- qcodes/instrument/parameter.py | 13 +- .../signal_hound/USB_SA124B.py | 4 +- 5 files changed, 222 insertions(+), 182 deletions(-) diff --git a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb index a58fd20b436..1845a1fdc40 100644 --- a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb +++ b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb @@ -19,7 +19,7 @@ "import numpy as np\n", "\n", "from qcodes.instrument.base import Instrument, Parameter\n", - "from qcodes.instrument.parameter import ArrayParameter2\n", + "from qcodes.instrument.parameter import ParameterWithSetpoints\n", "from qcodes.dataset.measurements import Measurement\n", "from qcodes.dataset.plotting import plot_by_id, load_by_id" ] @@ -52,7 +52,7 @@ "source": [ "\n", "\n", - "class TimeTrace(ArrayParameter2):\n", + "class TimeTrace(ParameterWithSetpoints):\n", " \n", " def get_raw(self):\n", " npts = self.root_instrument.npts()\n", @@ -61,7 +61,7 @@ " return timetrace(npts, dt)\n", " \n", "\n", - "class Periodogram(ArrayParameter2):\n", + "class Periodogram(ParameterWithSetpoints):\n", " \n", " def get_raw(self):\n", " npts = self.root_instrument.npts()\n", @@ -156,7 +156,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 101\n" + "Starting experimental run with id: 947\n" ] } ], @@ -179,12 +179,14 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -201,7 +203,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 102\n" + "Starting experimental run with id: 948\n" ] } ], @@ -221,12 +223,14 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -250,7 +254,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 103\n" + "Starting experimental run with id: 949\n" ] } ], @@ -273,12 +277,14 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -304,7 +310,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 104\n" + "Starting experimental run with id: 950\n" ] } ], @@ -330,12 +336,14 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -361,7 +369,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 105\n" + "Starting experimental run with id: 951\n" ] } ], @@ -389,12 +397,14 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -402,6 +412,20 @@ "_ = plot_by_id(dataid)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -426,7 +450,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.6.6" } }, "nbformat": 4, diff --git a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb index ba8cdbc751f..32d14da0704 100644 --- a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb +++ b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb @@ -4,9 +4,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Simple Example of new ArrayParameter\n", - "\n", - "This notebook has an example of a new simpler ArrayParameter\n" + "# Simple Example of ParameterWithSetpoints\n", + "This notebook has an example of a new simpler ArrayParameter replacement\n" ] }, { @@ -55,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "from qcodes.instrument.parameter import ArrayParameter2, GeneratedSetPoints" + "from qcodes.instrument.parameter import ParameterWithSetpoints, GeneratedSetPoints" ] }, { @@ -68,11 +67,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "class DummyArray(ArrayParameter2):\n", + "class DummyArray(ParameterWithSetpoints):\n", " \n", " def get_raw(self):\n", " npoints = self.root_instrument.n_points()\n", @@ -125,7 +124,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -141,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -159,7 +158,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 9, "metadata": { "scrolled": true }, @@ -215,7 +214,7 @@ " 495., 496., 497., 498., 499., 500.])" ] }, - "execution_count": 21, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -233,7 +232,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 10, "metadata": { "scrolled": true }, @@ -241,110 +240,110 @@ { "data": { "text/plain": [ - "array([0.31281518, 0.96887871, 0.42191194, 0.51714415, 0.25538286,\n", - " 0.92696486, 0.76954697, 0.51712345, 0.48111713, 0.61014766,\n", - " 0.42801603, 0.43561301, 0.64152132, 0.24845664, 0.68491269,\n", - " 0.57899917, 0.16974739, 0.18945099, 0.77348716, 0.32345713,\n", - " 0.32283512, 0.03025562, 0.91810724, 0.57521798, 0.58470989,\n", - " 0.38120617, 0.46536914, 0.48650925, 0.30560833, 0.78322953,\n", - " 0.93716312, 0.60605105, 0.75239911, 0.96351199, 0.32925186,\n", - " 0.71956489, 0.49513814, 0.40072415, 0.71484636, 0.47744867,\n", - " 0.99183756, 0.42884688, 0.87046585, 0.97636722, 0.80768148,\n", - " 0.47275855, 0.04567205, 0.80345861, 0.16429275, 0.98433221,\n", - " 0.31342919, 0.25533898, 0.71032451, 0.03503889, 0.69431169,\n", - " 0.85934569, 0.15493456, 0.350528 , 0.13867757, 0.88801413,\n", - " 0.12544615, 0.71695272, 0.80233482, 0.95412588, 0.08481348,\n", - " 0.88858004, 0.20740531, 0.62895786, 0.7094034 , 0.71663199,\n", - " 0.04516419, 0.25645949, 0.3619041 , 0.22624793, 0.03096165,\n", - " 0.50486112, 0.38058129, 0.38549274, 0.93265042, 0.69570252,\n", - " 0.9715744 , 0.26551269, 0.0278466 , 0.47564881, 0.14327013,\n", - " 0.65544137, 0.37554881, 0.81038091, 0.4373319 , 0.63655817,\n", - " 0.84999389, 0.48549494, 0.37636679, 0.24317791, 0.46666367,\n", - " 0.93993374, 0.2030196 , 0.20372072, 0.55596547, 0.64384574,\n", - " 0.55032748, 0.18346428, 0.13315848, 0.4444626 , 0.57653102,\n", - " 0.28088507, 0.47296397, 0.19810506, 0.02489858, 0.08292104,\n", - " 0.15122852, 0.02681189, 0.1825864 , 0.83923332, 0.82979598,\n", - " 0.12532781, 0.28667028, 0.06138414, 0.54201822, 0.28361495,\n", - " 0.04006816, 0.55588607, 0.08477299, 0.2226377 , 0.74544186,\n", - " 0.248556 , 0.90649953, 0.09848282, 0.63803225, 0.54836512,\n", - " 0.09148153, 0.14109837, 0.62075636, 0.52826137, 0.8763575 ,\n", - " 0.48961966, 0.24877176, 0.89193214, 0.7763051 , 0.6191885 ,\n", - " 0.93309929, 0.48183231, 0.38190092, 0.76675634, 0.31256475,\n", - " 0.64081171, 0.23996295, 0.17831513, 0.70911486, 0.3689516 ,\n", - " 0.77318391, 0.26551174, 0.9332016 , 0.80833114, 0.94929732,\n", - " 0.05899685, 0.14579488, 0.50757545, 0.84313475, 0.67681984,\n", - " 0.09312281, 0.17850811, 0.30471426, 0.70653125, 0.94016408,\n", - " 0.77204967, 0.78658342, 0.96252718, 0.05135915, 0.6104287 ,\n", - " 0.57842423, 0.54790475, 0.18708696, 0.40089462, 0.61792494,\n", - " 0.78666442, 0.45664661, 0.57400101, 0.21632045, 0.65836317,\n", - " 0.41728132, 0.09314095, 0.39881779, 0.69329242, 0.89670779,\n", - " 0.39077226, 0.36796047, 0.51413186, 0.24017188, 0.96503661,\n", - " 0.39737534, 0.14966974, 0.05272144, 0.07344577, 0.65384573,\n", - " 0.3244456 , 0.93881849, 0.77149932, 0.34256363, 0.57171536,\n", - " 0.99633436, 0.7128691 , 0.53621015, 0.20434432, 0.95889797,\n", - " 0.14452839, 0.52756577, 0.59106331, 0.3081482 , 0.4549849 ,\n", - " 0.20716477, 0.46569662, 0.74935475, 0.43593272, 0.27032474,\n", - " 0.76637407, 0.88225447, 0.65898922, 0.80142354, 0.14939703,\n", - " 0.54069258, 0.78950072, 0.83605732, 0.62979079, 0.21252879,\n", - " 0.60680212, 0.97419554, 0.77182435, 0.75763177, 0.97771958,\n", - " 0.91581111, 0.7219678 , 0.96016159, 0.65960683, 0.23570303,\n", - " 0.33695877, 0.23561085, 0.82518603, 0.94735652, 0.52801753,\n", - " 0.62309437, 0.98345045, 0.35983667, 0.07843121, 0.09146102,\n", - " 0.66973072, 0.93494067, 0.05280839, 0.93756376, 0.7293141 ,\n", - " 0.50768684, 0.14962689, 0.2658266 , 0.27975887, 0.96575044,\n", - " 0.86352484, 0.00677849, 0.60706878, 0.60814407, 0.12029253,\n", - " 0.34831538, 0.34223691, 0.58388414, 0.681435 , 0.21728724,\n", - " 0.94635087, 0.33127465, 0.64361487, 0.92241564, 0.59245856,\n", - " 0.1148949 , 0.7021584 , 0.11996621, 0.64843461, 0.94555061,\n", - " 0.70387657, 0.77887487, 0.72795828, 0.68279723, 0.39879606,\n", - " 0.1533654 , 0.38515401, 0.71375073, 0.17799896, 0.0252395 ,\n", - " 0.06283647, 0.84102243, 0.45017289, 0.29994363, 0.58409358,\n", - " 0.80281348, 0.79188333, 0.1162714 , 0.32685503, 0.75942253,\n", - " 0.38373489, 0.79152529, 0.97062294, 0.67297296, 0.79336539,\n", - " 0.43884364, 0.24561457, 0.65555045, 0.87768973, 0.64103826,\n", - " 0.2666453 , 0.1391131 , 0.86647697, 0.61714395, 0.41203585,\n", - " 0.11707366, 0.95913778, 0.05950737, 0.74316187, 0.24973516,\n", - " 0.55441886, 0.19049959, 0.72943378, 0.14485682, 0.23767495,\n", - " 0.23655284, 0.75358185, 0.11639362, 0.22699845, 0.58859088,\n", - " 0.19922609, 0.59756317, 0.31772437, 0.31891757, 0.61702834,\n", - " 0.2307571 , 0.71656227, 0.77801287, 0.61430522, 0.43949158,\n", - " 0.904222 , 0.13305298, 0.97109297, 0.03946522, 0.27349123,\n", - " 0.60728714, 0.11184083, 0.20264691, 0.41851126, 0.34208404,\n", - " 0.3516932 , 0.72207464, 0.62215237, 0.83973124, 0.61972589,\n", - " 0.00746499, 0.67415024, 0.64700587, 0.31843831, 0.85093758,\n", - " 0.36074848, 0.26198126, 0.55974394, 0.7755382 , 0.96214801,\n", - " 0.60038967, 0.5871515 , 0.97103239, 0.25660708, 0.8394608 ,\n", - " 0.61362974, 0.7721306 , 0.41902284, 0.56507279, 0.97512555,\n", - " 0.1757342 , 0.12194126, 0.72601828, 0.46489845, 0.20108013,\n", - " 0.12265486, 0.32739885, 0.23558657, 0.02516245, 0.90309388,\n", - " 0.71132001, 0.35639495, 0.99692481, 0.13415441, 0.65833817,\n", - " 0.11460708, 0.51822322, 0.53973366, 0.81536775, 0.13440548,\n", - " 0.48233264, 0.25445079, 0.00434424, 0.84816563, 0.02711536,\n", - " 0.21425029, 0.07758158, 0.02883053, 0.56527235, 0.19727065,\n", - " 0.49378938, 0.66257068, 0.99112211, 0.49515019, 0.45807055,\n", - " 0.24407957, 0.80594336, 0.52918217, 0.7366867 , 0.12172603,\n", - " 0.50720039, 0.89600683, 0.03299381, 0.87402446, 0.03942597,\n", - " 0.4398926 , 0.56602433, 0.1827016 , 0.34461014, 0.48292586,\n", - " 0.37908904, 0.05441919, 0.20705179, 0.34375954, 0.6649455 ,\n", - " 0.0731173 , 0.10959237, 0.98139206, 0.03566843, 0.00688507,\n", - " 0.91668891, 0.91156237, 0.65782263, 0.15321753, 0.12761921,\n", - " 0.70015197, 0.5353978 , 0.48899851, 0.92041438, 0.58646024,\n", - " 0.24802929, 0.58023147, 0.51882816, 0.49366176, 0.03196893,\n", - " 0.56670287, 0.06277128, 0.54048722, 0.85678255, 0.31840659,\n", - " 0.60387901, 0.25282476, 0.62576788, 0.34045001, 0.78477856,\n", - " 0.19135518, 0.89802393, 0.56130128, 0.54358126, 0.70889138,\n", - " 0.23780924, 0.43899571, 0.04051872, 0.73162057, 0.7630328 ,\n", - " 0.42628733, 0.5824199 , 0.51831109, 0.5821532 , 0.01817897,\n", - " 0.20330086, 0.02747431, 0.15170385, 0.63457024, 0.30606336,\n", - " 0.15690499, 0.75987837, 0.87250445, 0.34596773, 0.35767279,\n", - " 0.42499385, 0.14849033, 0.79368317, 0.08853673, 0.87720111,\n", - " 0.3156627 , 0.73408487, 0.16822168, 0.13283555, 0.35081781,\n", - " 0.23496507, 0.11859108, 0.19449802, 0.8220064 , 0.30034061,\n", - " 0.61608037, 0.64891939, 0.15747444, 0.40561231, 0.23300349,\n", - " 0.11877202])" + "array([0.37372587, 0.54861787, 0.53155288, 0.82667582, 0.94220873,\n", + " 0.0698023 , 0.89762473, 0.40402402, 0.94676787, 0.72479779,\n", + " 0.90016702, 0.50196169, 0.67613499, 0.96529924, 0.15008748,\n", + " 0.44617032, 0.77400385, 0.36104437, 0.6286802 , 0.69278277,\n", + " 0.12981568, 0.70792455, 0.63326382, 0.79600711, 0.77696625,\n", + " 0.60408452, 0.34930137, 0.33298155, 0.99237339, 0.72181006,\n", + " 0.24177301, 0.38409252, 0.13977054, 0.46336893, 0.29702444,\n", + " 0.32585009, 0.85559257, 0.506369 , 0.79234633, 0.91855242,\n", + " 0.91216349, 0.82632103, 0.15051881, 0.38302095, 0.39616307,\n", + " 0.32864887, 0.67891701, 0.01545452, 0.32810263, 0.84456954,\n", + " 0.30411356, 0.83792683, 0.18423625, 0.76232546, 0.62204577,\n", + " 0.28122632, 0.90895218, 0.47174043, 0.0835899 , 0.880365 ,\n", + " 0.09111603, 0.50584601, 0.56714919, 0.57147067, 0.85644402,\n", + " 0.22211664, 0.05509187, 0.95254653, 0.93371861, 0.97754025,\n", + " 0.0207392 , 0.28635372, 0.63367136, 0.0663695 , 0.70019442,\n", + " 0.40926177, 0.42111847, 0.85448678, 0.98820638, 0.94779916,\n", + " 0.25279355, 0.38715305, 0.30811057, 0.8744069 , 0.50608295,\n", + " 0.58995161, 0.58200316, 0.58201891, 0.93918669, 0.6899701 ,\n", + " 0.95871603, 0.14629169, 0.80691971, 0.99692501, 0.17309138,\n", + " 0.40671056, 0.87719149, 0.68771378, 0.08381251, 0.14822247,\n", + " 0.69180229, 0.03358827, 0.30626825, 0.33936864, 0.88937098,\n", + " 0.99683227, 0.7537689 , 0.35666654, 0.23870022, 0.80237453,\n", + " 0.83317602, 0.56290746, 0.4612086 , 0.59187958, 0.35496415,\n", + " 0.76680147, 0.72366515, 0.53806547, 0.73491729, 0.87097106,\n", + " 0.22250074, 0.4319 , 0.25040755, 0.4204853 , 0.57152887,\n", + " 0.67989035, 0.51488572, 0.12774031, 0.86615569, 0.78384103,\n", + " 0.04802505, 0.65392064, 0.96986131, 0.47990375, 0.3774105 ,\n", + " 0.06543123, 0.41360314, 0.1389294 , 0.23166719, 0.67111829,\n", + " 0.59806864, 0.73826979, 0.4013829 , 0.63824427, 0.44717827,\n", + " 0.15403842, 0.39021108, 0.10353845, 0.96664997, 0.41367465,\n", + " 0.22059292, 0.17918976, 0.96500464, 0.51467301, 0.89966624,\n", + " 0.93987921, 0.94166864, 0.64683108, 0.55641748, 0.9484579 ,\n", + " 0.66408577, 0.37486359, 0.65857553, 0.00120706, 0.76021654,\n", + " 0.95142316, 0.74106431, 0.3687487 , 0.81576676, 0.89905403,\n", + " 0.60252817, 0.52068992, 0.99020434, 0.01758782, 0.26871668,\n", + " 0.42934743, 0.74147531, 0.02036298, 0.90464033, 0.67078621,\n", + " 0.55625392, 0.61639495, 0.68145904, 0.18213379, 0.03731415,\n", + " 0.28217922, 0.82413099, 0.41451497, 0.06819495, 0.67933438,\n", + " 0.48485664, 0.02562523, 0.99595955, 0.8278784 , 0.56357999,\n", + " 0.45688242, 0.15482338, 0.88100967, 0.75521795, 0.66280644,\n", + " 0.43293394, 0.70636499, 0.83458264, 0.16970696, 0.47818101,\n", + " 0.08842654, 0.77442703, 0.56663918, 0.24441029, 0.55706783,\n", + " 0.08530588, 0.48254471, 0.90653557, 0.86716833, 0.92738514,\n", + " 0.29735555, 0.5957369 , 0.34662178, 0.14905592, 0.84934635,\n", + " 0.37038126, 0.91797818, 0.10743678, 0.33358987, 0.61751291,\n", + " 0.56708866, 0.96416561, 0.9008846 , 0.5365646 , 0.33294292,\n", + " 0.7055552 , 0.22700866, 0.21832081, 0.37975166, 0.69098247,\n", + " 0.10769966, 0.14557844, 0.14896331, 0.37194517, 0.45441072,\n", + " 0.83939733, 0.99817352, 0.36444098, 0.043637 , 0.19484866,\n", + " 0.39253182, 0.75448118, 0.35597998, 0.80725856, 0.95531812,\n", + " 0.79183714, 0.36342638, 0.45123011, 0.92610209, 0.25520695,\n", + " 0.85375401, 0.01310321, 0.48663791, 0.48385191, 0.8494894 ,\n", + " 0.76816717, 0.72400051, 0.0430897 , 0.15606243, 0.53290784,\n", + " 0.09257425, 0.75460404, 0.74206088, 0.61720626, 0.51084909,\n", + " 0.58411453, 0.47311666, 0.53830169, 0.9681255 , 0.79663431,\n", + " 0.57598398, 0.77865371, 0.65301602, 0.18408085, 0.80375723,\n", + " 0.23633886, 0.58244941, 0.29898102, 0.02252307, 0.98082483,\n", + " 0.23015448, 0.70841724, 0.05523285, 0.49451749, 0.35346533,\n", + " 0.85056982, 0.33981886, 0.06833761, 0.79821593, 0.11604247,\n", + " 0.8953603 , 0.46323585, 0.23137089, 0.44835628, 0.80901788,\n", + " 0.42361957, 0.51037851, 0.23792164, 0.7941132 , 0.76321701,\n", + " 0.11911182, 0.84181059, 0.60137409, 0.34603324, 0.22177182,\n", + " 0.10613795, 0.89584437, 0.64215604, 0.2739601 , 0.76154826,\n", + " 0.04708115, 0.81540537, 0.12827219, 0.01783416, 0.62473422,\n", + " 0.6454418 , 0.35580161, 0.25226381, 0.15315039, 0.06409371,\n", + " 0.82481876, 0.26274587, 0.77689317, 0.28502571, 0.11676692,\n", + " 0.21020535, 0.58340203, 0.50298104, 0.66517868, 0.91702034,\n", + " 0.41895255, 0.48976598, 0.71751388, 0.55612794, 0.79018665,\n", + " 0.08031651, 0.93057851, 0.56953056, 0.04527181, 0.88304957,\n", + " 0.70831083, 0.90265482, 0.94031171, 0.2569966 , 0.66892006,\n", + " 0.66635678, 0.27309862, 0.03279321, 0.7976703 , 0.50451827,\n", + " 0.75593387, 0.35091271, 0.76169186, 0.57906099, 0.98890751,\n", + " 0.96141125, 0.25731111, 0.67022349, 0.30738175, 0.22752395,\n", + " 0.88743371, 0.6975126 , 0.90094769, 0.55723621, 0.17498322,\n", + " 0.23819869, 0.3564374 , 0.80282856, 0.30243351, 0.80448796,\n", + " 0.48466329, 0.98000332, 0.02199852, 0.18488749, 0.54550893,\n", + " 0.86812643, 0.83792429, 0.89461096, 0.88250996, 0.42808942,\n", + " 0.59296736, 0.79860916, 0.30380101, 0.43271408, 0.15841563,\n", + " 0.56869869, 0.04184787, 0.10550598, 0.60942529, 0.4265301 ,\n", + " 0.57083876, 0.82435567, 0.59211889, 0.96031419, 0.67952074,\n", + " 0.37334926, 0.3645627 , 0.00962004, 0.46270116, 0.24393275,\n", + " 0.61877639, 0.72515794, 0.74112891, 0.78423151, 0.38865816,\n", + " 0.52355693, 0.98749161, 0.0240849 , 0.55514309, 0.01958487,\n", + " 0.849384 , 0.59643945, 0.72927759, 0.50640776, 0.47260815,\n", + " 0.02341713, 0.18155492, 0.92489797, 0.25403256, 0.10852141,\n", + " 0.64066968, 0.77210979, 0.11233653, 0.67487216, 0.66589406,\n", + " 0.69246635, 0.81106247, 0.04426596, 0.72241094, 0.61934481,\n", + " 0.67953836, 0.33271667, 0.70431201, 0.49538386, 0.70481405,\n", + " 0.51488965, 0.35365375, 0.96189495, 0.08626799, 0.65469915,\n", + " 0.75678647, 0.13191874, 0.68800181, 0.3976978 , 0.75082862,\n", + " 0.9238525 , 0.19926841, 0.52864871, 0.84631558, 0.08041432,\n", + " 0.61617623, 0.47972956, 0.41253579, 0.89873016, 0.49668532,\n", + " 0.28110437, 0.71319872, 0.38127862, 0.2969393 , 0.6869966 ,\n", + " 0.93906833, 0.05512929, 0.46130136, 0.31505291, 0.57178749,\n", + " 0.77410248, 0.43127678, 0.46184098, 0.30312938, 0.93041753,\n", + " 0.51114825, 0.79740875, 0.76236662, 0.46370778, 0.98322976,\n", + " 0.03513679, 0.3587125 , 0.13594183, 0.59490432, 0.77843549,\n", + " 0.69222248, 0.89102323, 0.69021418, 0.81951953, 0.13221865,\n", + " 0.86460461, 0.83135051, 0.15770558, 0.18465204, 0.17177554,\n", + " 0.61530353, 0.64739044, 0.40496839, 0.49301272, 0.86611209,\n", + " 0.86025078])" ] }, - "execution_count": 22, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -362,14 +361,14 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 614\n" + "Starting experimental run with id: 952\n" ] } ], @@ -385,7 +384,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -401,22 +400,22 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 26, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAAEWCAYAAABBvWFzAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvqOYd8AAAIABJREFUeJzsfXmcJEWV//dVdc8MNwiogOIo4IEiqIgnXojnqqy668WKqIuuq6s/11W88UARD5RVcUEEFMETFRSR+2aG+75mgBnmZu6ze7q76v3+iIjMOF5ERlZXdTdDfT+fmeqMjIx4mRkZL94ZxMzoo48++uijj/GiMdkE9NFHH330sWWgz1D66KOPPvroCvoMpY8++uijj66gz1D66KOPPvroCvoMpY8++uijj66gz1D66KOPPvroCvoMpY8tDkT0BSL6+WTTkQMiOoaIzuxh+5cT0Yd71X4nIKKfEdGXM+sm6SeifYnoxu5RN7VARPOI6LUZ9Z5ARPcQ0fSJoCuGPkMZB/TLHiKiDUS0lIhOJ6JtJ6DfjxHRsfrvK4nouda56UR0AhEtJqLVRPRTIhq0zl9ORMOa5g1EdJ917s1EdDURrdH3cwoRbZdJ00wiYqtd8+9d3bz3HDDzt5h5widRIvoAEV3dw/bnEdEyItrGKvswEV0+jjaZiPauUf90Ivpmp/0BADN/lJm/MZ42LHwDwPe61NajFsy8DMBlAI6aTDr6DGX8eAszbwvgAADPA/D5CejzBQBuIqIGgGcBuNs6dzSAAwE8B8DTATwfwJe86z/OzNvqf8+wyncA8E0Au+t2nwTguzVp29Fqe1tm/m3N68cFIhqYyP4mAQMAPjnZRHQKImp2sa3dALwawJ+71eajHL8G8JHJJKDPULoEZl4K4B9QjAVAKK77K1i9OvwoEc3R0sRPiIgyujsQwE0AngHgIWYes869BcCJzLyKmZcDOBHABzPv4SxmvoCZNzHzagCnAHhZzrUpENE0IrqViD6hj5tEdA0RfUUfH0NEfyCi3xLReiK6mYj2t67fnYj+SETLieghIvov65y59kwiWgfgA7YayZKcjiSiBfo5f5SIXkhEt2tp7McevR/U6oPVRPQPInqKdU58Z0T0LAA/A/ASLZmtiTyLpxLRFfo+LwKwi3f+rUR0l6brct2uje8C+AwR7Rhp/1AiupeI1ur7io4nIrpS/3mbkSYlKctIMUR0FID3Afisrn+ePv8sTesaTftbrWtPJ6KTiOh8ItoI4NW2lENEOxHRX/W7Xa3/flKMZg+HAriZmYet/uYR0Wf0u12rx9QM6/y/E9FcIlpFROcS0e6RZzNDj6mV+r5uIKIn6HNH6vGxnogeJKKPWNe9iogWEtFniegRIlpCRIcR0ZuI6H7d7xes+smx79HUIKKjiegBTdfviOhxVpXZAJ5mj9eJRp+hdAn6I3gjgLk1L/0nAC8EsD+AfwXw+kj70/XAXgslfdwGxVT21+VfNFXhTiIE4ElEtINV9m0iWkFqUn9VgrZXALir5v0EYOYRAIcD+LqeII8G0ARwrFXtbQB+D+BxAM4C8GciGiQlhZ0Hdb97ADgEwKeI6PXetX8AsCPUKk3CiwDsA+BdAH4I4IsAXgvg2QD+lYheCQBEdBiALwB4O4BdAVwF4GyvreCdMfM9AD4K4DotmYkTvr63m6AYyTcAHGFOENHTdV+f0n2fD+A8IppmXX8jgMsBfMZvmIh2AfBHKIl0FwAPILEgYOZX6D/3z5EmmflkqOd7vK7/FlLq1PMAXAjg8QA+AeDXRGRLvu+FetfbAfBVgg0ApwF4CoA9AQwB+DHysB+A+4TyfwXwBgBPBfBcAB8AACJ6DYBv6/O7AZgP4DeRto+AktifDGBnqHc7pM89AjUGtgdwJIATiOj51rVPBDADarx+BWphdjiUZuFgAF8hoqdZ9cWxL9D0XwAOA/BKKC3CagA/MSf1wnIu1LicHDBz/1+H/wDMA7ABwHoADOASKJWPOX85gA9bxx8AcLV1zABebh3/DsDRFX1+GMAJ+u8LARzknf8mgGugJqQnQq1aGMBu+vyLoD7s6VAfzXoAewn9HAo1YJ+e+Sxm6n7WeP+eZdX5bwD36nb3scqPATDLOm4AWAL18b0IwMNeX58HcJp17ZXe+WMAnOnRtYd1fiWAd1nHfwTwKf333wF8yKNlE4CnVL0z//0Kz2hPAGMAtrHKzrJo/TKA33l9LwLwKmu8vRZqQbFWv+MPA7hcn3+/9xwJwEJ7DAo0MYC9Y2PUrwPgdADftM4dDGApgIZVdjaAY6z6v/Tac9rwzh0AYHXsG/LqngLgOOGbPNw6Ph7Az/Tfp0IxQ3NuWwCjAGYKbX8QwLUAnpsx9v8M4JP671dBMZ6mPt5OP78XWfVvAnBY1di337n++x4Ah1h1d9P0D1hl1wB4f84324t/fQll/DiMmbeDGkjPhKfCyMBS6+9NUIM8ABH9RqtRTgLwYS2pHALgQiK63qp6LIBbANwK9UH8GWrQPQIAzDybmdcz82ZmPgNqAL7J6+vFUBPdO5n5/pr3swsz72j9u8c6dwbUBH8+M8/xrltg/mDmNtREuDvUynV3LYWt0c/gCwCeIF2bwDLr7yHh2Dz3pwD4kdXXKqiJeQ+rftY7E7A71GS50Sqb750vjvVzWOD1DWa+E8BfoSQ9v337ObJ9rNVRxlni4Eyaq7A7gAWaVoP5Hs3R90NEWxPR/xHRfFIqyysB7Eh5tpbVUBO2j9j78Z/vBqjFhfN8NX4FpcL+DSkHl+ON1EBEbySiWVp9tQbq+7G/+5XM3NJ/G6kmNt6A+Nj38RQAf7LG5j0AWnC/he2gFnKTgj5D6RKY+QqolZftcbIRwNbW8RPH0f67oUTi1VCqnfcDOFtP2gdZ9YaY+ePMvAczPw3qg7nJGuBB07BUZET0PADnAvggM1/SKb0R/BRqInw9Eb3cO/dki4YGlEPAYqiP7SGPSW3HzDYT7GbK7AUAPuL1txUzX5txbRUdSwDsRJaXFpTUYrAYatIAABARQT2XRUJbXwXw73AnwyVwnyPZx8z8bC6dJa6K0OiMWSLyx6x/j4sBPFm/M/uebJpTz+W/oWyBL2Lm7aHUrEDC9mPhdijHk1z4z3cbKHVW8HyZeZSZv8bM+wJ4KZSK6/2k3HL/CPWdP4GVavP8THpjiI19HwsAvNEbmzOYeZG+dgDA3lDq4UlBn6F0Fz8EcCgRGcP8rQDerldhewP40DjbfxaABzRzeD6UPt0BEe1ByohNWtL4MtTkAyLakYherw2OA0T0PqgP+B/6/HMAXADgE8x8ntD2MdShiyoR/RuUDvkDULrgM8h1sX4BEb1dfxSfArAZwCwA1wNYR0SfI6KtSBn0n0NEL+yEjgz8DMDniejZmu4diOhfMq9dBmWvmiadZOb5UO/sa6QcFV4O5URh8DsAbyaiQ/Rq+L+hnkPAzJh5LoDfQj1Lg78BeLb1HP8L1YuYZQBsff5tuo0DSBmzj6moPxuKCX1W27xepe8pZpvwsR3Uin2NNjB/NfM6ALgIwPPJMrpX4CwAR+p7mw7gWwBmM/M8vyIRvZqI9tOS0jooKb8FYBqUung5gDEieiOA19WgWUJs7Pv4GYBjjdGdiHYlordZ5w8CME+Ps0lBn6F0Eay8qn4JNYkDwAkARqA+wjMQNxjn4gUAbtZ/Px9KF+tjL6gJaKPu82hmvlCfG4SysSwHsALKgHoYMxvD5n9D6eVPtVQjtlH+yVAqshTWkBuH8mki2hOK2b6fmTcw81lQE+sJ1nV/gTKYrwbwbwDerleJLagJ6gAAD2m6fw5lMO06mPlPAL4DpepYB+BOKGeLHFwK5cSwlIhWROq8F8outApq8vyl1fd9UMbb/4W6z7dAuaWPRNr6OoBC2mHmFQD+BcBxUJLpPqh+X8dAMfc1RPSvWsX5dQAXA5iD0Ih+KoB9df0/a9reCvWMVkBJoe9n5nsr+jX4IYCt9LWzoBY0WWAVe3EplFE7p/4lUN/mH6Gkub0AvDtS/YlQjh7roFRLV0DZutZDMerfQY3V90JJ9OOBOPaFej/SfV1IROuhnteLrPPvg2I6kwbShpw++qgEEd0KZRRc2eV2j4Ey+h7ezXb72PJBRPtCLZwO4kfhZNatsU9Ej4dies9jy416orGlB4H10UUw8wHVtfroY+LAzHdDuXA/psHMj0CpxCcVfZVXH3300UcfXUFf5dVHH3300UdX0JdQ+uijjz766AoeUzaUXXbZhWfOnDnZZPTRRx99PKpw0003rWDmXavqPaYYysyZM3HjjVvs1gl99NFHHz0BEWXFtvRVXn300UcffXQFfYbSRx999NFHV9BnKH300UcffXQFfYbSRx999NFHV9BnKH300UcffXQFE85QiOgXpLbGvNMqexwRXURqW9WLiGgnXU5EdCKpLTtvJ2tXNCI6QtefQ0RHSH310UcfffQxcZgMCeV0qO05bRwN4BJm3gdq10OzcdAboTKm7gPgKKjNpWCluX4RVMrmrxom1EcfffTRx+RgwhkKM18JlbrbxtugMoZC/x5mlf+SFWZB7eS2G9S+6xcx8ypmXg21L4LPpProY0KwfP3mySahj5pYtGYIZ86aj7WbRjFn2XrMfrCrCbQfs5gqNpQnMPMSANC/j9fle8DdPnShLouVByCio4joRiK6cfny5V0nvI/HNi66exleeOzFuGZubPuTxwb+fMsibBoZm2wysvHZP9yGL/35Tpx/5xIcesKVeNfJ0n5WfdTFVGEoMUjbanKiPCxkPpmZD2TmA3fdtTJzQB991MItD692frdEtNuMj591c/Qeb3l4NT7121vx/G9chPuWrp9g6jrD+mHF/EZb7UmmZMvCVGEoy7QqC/r3EV2+ENZ+yyj3Wo6VP2qwdmgUqzfGNuKbGjjtmodw0/wtd6LsBgab6hMabW25WbsfWb8Zf719CT7yK2mDUGDzmJqUh0fbeP0Pr+yg/WEMjbSy668fHsXBx186LiZukqy321vue5sMTBWGci4A46l1BNSWmKb8/db+6Gu1SuwfAF5HRDtpY/zrdNmjBvt/7UI87xsXTTYZSXztvLvxjpOC7cz7sDBtwDCULWule9bsh/HTy+dm1Z0+ML5p5KBjL6k1zm5+eA0WrBrCDy66f1z9AkCfn3QXk+E2fDaA6wA8g4gWEtGHoPbAPpSI5gA4VB8DwPkAHgQwF8ApAD4GAMy8CsA3ANyg/31dlz1mcf+y9bj8vkeqK/bRVQw2lfZ1IhjKFfcvx5GnXY+J2MPoC3+6A8dfcB8AgLSCOdbrtAyGwsyYefTf8J0L5K3m716yrrKN7/7jXhzw9QvRaqtn3WxImu88sL6bdg+f5dVzVuDK+x9bdtsJzzbMzO+JnDpEqMsA/jPSzi8A/KKLpD2q8boTlKph3nFv7nrbm0bGsPW0LSMx9fBoC4PNxrgmIxsDjYlTef37GTdipNXGSKuN6QPNnvdnUPWkjNovBSMJ/N8VD+Bzb3hmR3T85LIHAACGdzep3ju8bcEatJnxvD13KlReveTNh586G0Bvvsmpiqmi8nrU4Zhz78LMo/822WQEGG21u76C3fcrjyptYhLP/PIF+NRvb+1ae4NbqMqr2+jmmGxp7tSouSh420+uwT//9FpNj6YrKnf10Qn6DKVDnH7tvMkmQcQHT78Br/n+FVg3PDrZpIwLcx9Z37P4jvNuS/tvXHz3MtycafAdaEycystgsnbtjvVrq41iQkM3STb91ZVQ5LbG3UQfFvoMZQvDVXNW4KEVGzHrgUd3oNZrf3AlXv6dS8Vza4d6yyw//Msb8faf5hmJzeS2JXt5Vem8bEYTM9CbOtQFJmAkFKO2POnyBzDz6L9hrAZTNyT30obyWESfoWyh2BJWXsYd1cZdi9di/69diD/fsmgSKAoxphnJyARIKEY9M9XmQHtSjtl2uqla8hnKiZfMASCPlypMtWf5aMeWYWntQ8CW+aXcs0QFzl05ZznG9MTyzhc8adLoMTTUWR3XBTPjvmVlwODk6f3lfutIKN3AmMdQzG+rRifGptOPQ+ku+hLKFgpmZQu49N5lXW970ZohHPD1C/HQio1db7sOPvP72/CZ39/W0bXdShNiXFh7qfI6/dp5eMMPryr6mOg5kBI6L2bGojVDxfH0wfSU0moz1mwaX0CvsVc1tPrM2OY7YQ59ftJd9BnKFgqGsgV88PQbu972ubcuxppNo/jN9Q93ve0qmJVlapLLwYr13clSYFbLvTTK37ForXM8EXEoTn8JVdvJVz7oRNBHVV7WtQd8fXwBvSNjJg4F+ldLKG3GyFgbC1ZtSl5vM55e2VAm+h1NFfQZyhaKXo7nLthVO4a5rU5osD/y0XZ3GEBhQ+lAf98pJnyqSnQ4y8vSG1V5dZFqw7xLlZfqc6zN+Mpf7sTBx1+WlIKGx1oFI+n2xH/v0nV41pcvwG0L11ZX3gLRZyhbKCZCzz5V1mCnXfNQVj177uiW7txIKD01ynuk8gSHvKSelO+1NRE2lM1jPkNR5WNtxhU6Mn1TIjfYppFWYdjvtsrri3+6E0OjLVz3KPey7BR9hjJOSCuckbF2T420OeiphNK7pjvC1867O2uladfo1kRibCjDoxMpoUywyqsIAqxG3MvLxbm3LcaJl8zpiLEXEkphQ9EqrxYXkkdKgh0aaZXJIbv8ody1WEkmW1XYkrZUPDbvuouQxuPTv/R3/NP/Xj3xxFiYCP/6qaQnzjGK28+kW8/HSCibx/Kz5daGNzl2SvqFdy3Nluac/hKsxJ+3Z0QmUn+s/NfZt+AHF92P+RX2DglGvdjwvLxG2+3i2TQSHGV4tFV4hPVqBA9N4AJjKqHvNjxOxAbkvZO8L8SGzb3b7KhIFjgZ/CTS59BoqzJJoU1vq1sqr9bEx4Z0ygyP0sbzI1/21FrXpbrz5+1cCcWgk/dQGOXJcxtucyF5pqToodHShtKrhdfwaA8XGFMYfQllnMhZpS9YtQnXPjCxO/ptGO4hQ9Gf62TKJ/6EsTnjA7ZX2t2aR8yE2C0GlYOJfu6mv5yxHmPqsUs7kXIDo7xmLGMtzmpvaKQF45NhV//b7Utq0xLto89Q+ugEOfPIK797Gd57yuzeE2Nh/TgZyrJ1w9Fzk+nlFUPOB+xIKF1TeamZaSJTeIy3q2XrhnHw8Zdi/sq8OKL0JO0Ohmi+xmgesCwSHIx4DMWovsba7dJ7K3G9I6FYBPznWTfjkcS4z4FZbNXZMGxLQp+hjBM5BtLJCJ5aP47kkHMfWY8XfeuSLlLTPcSed12GksMAYgbjeSs24q0/vhprN40WkslEqrzqrup/ftWDTmbsBas2YcGqoezA1DrdxarG3lsnjHhkzIuUNxKKpfJKtTs8Gvfy6pa3Xq9VXis39CZx6njRZyjjhBm3h3z/chz7t7snlxgL45FQ5q/MM5ROpk3el5JyVoT2pJbjXRSbXE68ZA5uX7gWF92zrLChTJbK6/L7HsH/XfFAsv5xf3c3tTKk1qVYqu+/h7hqSy7vyIbiR8o3QpWX36z9vjeNtLIYz3jQLZXXO0+6Fi/9tru4m/XgSrzgmxfjgjuXdqWPbqLPULqEB5ZvxClX1feg6RXWaYYS87p5tCL2/deXUKr7iiUbLIIrUXp59VTl5cehWMcfOO0GfPvv8i6IBj5trZocxb78tGsewkd+VZ19od1mXHz3smKCj0ouNR6bYV4j2qMujEMpvbz8BcMpVz1Y/L1h81jPAhsNuiWh3Dh/NRavddVwN81XWyvcumBNV/roJras2WYSMIU8Zx0YN9ZpGbvp+ci9p8ncnMhPvZLzAdsTa87KeP+vXSiWF+lfqLcM5fCfz8Z7Tp4VlNftK6bWyX1/duqVr513N/5xV5kfzjeZmBbPnD0fH/7ljfiTzgodm7jr3ItRbRkXcV/lpby85PZsprt+uGQoYz2SLEd6mNvNLHRiQaSTialH0aMMU3XHtzLAq/sWdNPmVGKmQyPVum+b3NyV6WX3PRJth6gMbIzNS4vXDHVsoL167gpc9+DKMA6lo9ZKGOabvXAwAo1wQajyUnVMwshl65SuP9ZVHYbSKBiK+65tlVeOKmv98FixoBjzJv7xjunSpb53H4dxm65KxDkZmHoUTUEwc3Rr3V6qzh9cvqHjgTmeVFVVPU4FJy+fkffKy+vI027Ag8s3iO0QqNKG8tLjLsWRp1+f1VcuxjtZ1WUoKfiSYl3VVh2GYiZrXxVpG+XNuLBfh/+81g+PFvT0KqlnL1Wg5v3FYn4mE32GkoEzZ83HPl/8O1ZtDBPOve+UWePyqIrhhnmr8JrvX4GzOszoO54BPVkR8KOtNi64c4nMuNuMg4+/tFCh+PN3ls7as6G024zbF1brof28ULaEkqPymvXgqmraamC8r6dgKLn9eb82AgHYt/cYdVmktzrzuZFQzArdjJNGEdjYFiUUf6zYNpRR72S3BHp7QTc00sLPr3qwa44bhqFORfvo1KNoCsKsBIYFI+1tC9fioru7v+fInGVqVXznos6ylo5n0pksTdaJl8zBR8+8WVQzjbbbWLBqCLMfUpOz/3HWtaG024xTr34Ib/3xNUHG3DooGMpEenmNm6G4E3J1f/kdGsYRbC/QBS+vRmGUN/SrY8e2osvWbBrBw9pbccwT122V12iPskTbY+2Ei+/HN/92D/56++JabcSeu7GPTkUJpZ96JQNGVxmLxu6Fy6j5CJrRSLE0xiehyOU3zV+NlRs290xPvER7s6zYEEqCflf+M89zGy7RZsbdS9YBUHaOOrDvu8qG0gtIq/1Wm7PHSqcSioRst+HI9bVsKA3XhmKuHGiGRvl3nHQdAGDecW8Oxoqt8vKZTbdg39a6IaXB2Li5ni0tpsY1EkpVqqHJwNSjaAqikFAiCd96oSEyuvmBRmevqBc63HecdC2O+tVNxdpzPD08sn4Yz/ryBY4ENmDlZDL4/Y0LVF9VDCXLhuKqQcwzSiUSBIRJsyi3bCgT6DYsMa86toChDo3y43nh3YhD8Y3yfiLIsYiXl+/JtX54rHhfvjdW11LyWA0ZJ5a632QsH99mPQ/5HpwTuSdPDH2GkoFCQolklI1NJnt/4Xz8Tk+IdWFWTgMdSygdXaaRvrgbnmNX3r8CQ6Mt/MLKflum0Cj7/58/3A4gfMb+yjK1/4WB/UycRIIVtxNT3zQsG8pE2p2kvuq4v5YLo/HLKIFRPiqhRGwotby81K+ZOMsFgSofa7XFcW+rI6c1G47b8ESovAx9dUdITKIx85A9bv9w00I8/Ut/L9R8k4U+Q8mA8feOBbrF9j4ZazNOvGROR32aCWKgIo6EmUV1TxFQ1sOJzjR99ZwVXdn/xTBPyR4RDc7TyFFduMkhOSqhbD/D1QT7DKdwyQYV72myk0PWef6dug2LCHitXDnq5dWBhDLiqbzsHRsl2OU7bj04QV5e5d+dqog3xiQUz4YEAOffoRJbznlkcrOc9xlKBmYMGpWXvGJIBTHN3HmbjvpsFSqv9PL5lKsexLO+ckFQPp7prWrcFx8IGJfcswyHnzrbkTTqdVb+aasufPgTj18na16wJRQu03T4DCX32f3nWTfjNh2tLM1lXWPmkVgPGzn7wRiYFW5d+cSxQUUm77o2lDqM2EjGRuVjOisi5SODwO5j+60GHVWSz1C69crYkVDiC6UUoiqvsVDCtINtJxN9hpKBKgkltcp5ys5bd9SncWesMrReM1f2UOqlH7xN0ZxHlDfa8vXjT1bXTEoo7rE/EeV8rK5RvnTtDB5xRVO5q+1evQKp3Vo2lJHxSyitQkrz6kbbkM/UipTXs1WxQi/K4wsRv3yw2XDGkr8Y7NZ305YYSs2mN43IDMX3crPbDtSzE4w+Q8lAaZSXJZSUHnb7rQY76tOstgab6QGy/5N3FMt7GdhoY632YNlx62m1+pDuqtgoSfioAxWXngh++K4DsPsOM7J08b7bcCybgN+SP8nkZs7tFUuXVV7VvZmxVLgN10y9YkOSLBoUMp8yyl5uu6M4lJZvQwmdOWy0HYbivmtfqunWO5O+v7rMKiZ1St6mRc2+hDL1MWOwcwml0/iEXBtKLLhpYrYABtZsUgxlh5qMU6KuKXh5lX3JNpRmg9BoUJ6E4qzoSqO8L6H4fcUmSR8+U+uV/Up6t6MZKwjzfIfHxp96RWLGamKvp3qpZ5SXHQDqSig2/G/3weUburIZnviOaub3ij0aX0JTdWWJcaLRZygZMBJKjKGkbCidGmvHMm0oUZ21PXm2uVZm0spv3OTyArB2SMWMdCqJ2WgmVpoxL6+BBmGgQVleTnaNVjvfhuLTE1frxPvrJqT3kyehqM+9ThwKM8sqL1FCiY/VbhjlY+7bpt/v/uM+8bqWxWz978mf5D90xo3j2gzPtG4zFDPOYl6icUQklMSCoBe5++pgSjEUIvp/RHQXEd1JRGcT0QwieioRzSaiOUT0WyKaputO18dz9fmZvaJrRkVgY0pC6TQ+IddtOEc3fdq183DYT67BNXPzVl5VqpAiDoVLlVez5kBOqrxq2FAGmg00GpSn8mrbH7m9ynbr+U0Fqqyo+qZHNpQMCSnHhmIYylCNSPk2l+PBrm3maPvRkaDyKtuRT3QSh2JgmqwaefajGWj6DKX3Xl5GRRdbkOa0YWOzoLLMfRa9xpRhKES0B4D/AnAgMz8HQBPAuwF8B8AJzLwPgNUAPqQv+RCA1cy8N4ATdL2eoEpCSblsupNY/seTUnktWjMU3XGu6Nfqy2z1OmdZnkthrpcXUKq8upF1WQpsNPBXsoaBDDQITcpTefnXlyovX0Jhh5GHTefZUHqldswJ3pNgGHZsYSQhKqEIzLjZoMSOjTJSC4E3n3gV/uf3tzntu22GjE6C7VLuawZjDKUuo2FmHPqDK7BROzzY78gwgLp7pFSqvKzz5llUBen2GlOGoWgMANiKiAYAbA1gCYDXAPiDPn8GgMP032/Tx9DnD6EeyXuDTQJRym04T0KpM78YJuV/RIvXDOFlx12K71+oxPvYpGUXbztdxVXE3BDHg4KhdGHulAIbDfz7HLP2xGg2KGul69tQzKEkoTQdhpInefQoi0cWcuJ0tEnIAAAgAElEQVRQDN11ti2OPdaYyiu2aIpK0on3dtfidfj9TQuL45gkWcW4bVoD1WlEVVh3x9M2lx6PNm1AabOqK6HEFml+HI7dX99tWIOZFwH4HoCHoRjJWgA3AVjDzObtLgSwh/57DwAL9LVjuv7OfrtEdBQR3UhENy5fvrwj2ogIMwaaCaN8yoZS/l1nzo2tOI177tVafZWjYthuhrJvrM9kKPl0cpGnqFN+Yl9npAJpcgwDGUsJpUGUJQ04WwBzOclJNhRHQsm0oeQyntrIyJeVZ/BVdcykmiNVti0Jxe7XvA+btAbJz2ZopIUv/+VOsX17nJ9eEcsUqrzyGKPdh/8uY4vBuhnE/cBae7war7rNkdRNNuav3FgENFatkWwmPQE+OFmYMgyFiHaCkjqeCmB3ANsAeKNQtVhYJs6VBcwnM/OBzHzgrrvu2jF90wcbcbfhXqi8Wkallb4mbkMp/95WR37nrrqq6DS+7swlk+qGR1PKWydlQ8mVUOwqtttwoCbwJJRcO1jg5VWDzS6qkaBSSuuRlSnArOhrSChAxG1YuLjRILHNX8+enxUvdcx5dyfp8O10BaNLXuV+g74NJbZwqy2heI/fvi8zb+QY5V/53cvx3lPULp0uw6iYB2p61/UKU4ahAHgtgIeYeTkzjwI4B8BLAeyoVWAA8CQAJgf0QgBPBgB9fgcA3d14wsKMgWZ0hZFrlK8z5cbUEn4bOavlbaYpG9CGmh9JDN0ctHZTJUMJn2eg8rKyMTcbhJwFuu/2GgtsZLBjuwrdhmNMvDMJ5ao5y/Gy4y4t0mdUwW62eGYZD8DUGKul8pJtKGaS9t2G/dUeMyeZfb1IeffYXFm16DL3++pn7IqX7rVLVv/rximh2CQZzUYsuayP2xaGW1bImRjC8/3AxhIPA3gxEW2tbSGHALgbwGUA3qnrHAHgL/rvc/Ux9PlLuYeJq6YPNqIrjJGxeLe+Z1Euyoyq8kWSe6INu9iswLttQxnr8N5iSHt5uWV2appmbhyKfb2dmbauDcVr10x0qVVqCncuUmn0b8vY7EvRZ0soqvMcI7K5rpBQMvpSXl76euuKWGCjgT35p15NHV8KX5Isnm9FG4bWj75yrzArQgTjlVDsd1RHQnHa5PTzliTHvoSiwcyzoYzrNwO4A4q2kwF8DsCniWgulI3kVH3JqQB21uWfBnB0L+mbPtCIrjDyJZQaKq/Mjz7HhmL67ZaEYmBchu0+6kK6SrIHxGwoTe3llafycRmgneTRp8m2oVS5AxtVTKeR8pVp9L2GbHIMnTk2FFOjsKHk2J2YxXpS6hWKGOVTjPWEi+6vpMHA38mh5Cfp+yjVo5Qdp1GXofjjz35HRkLxbbDMjIvuXiYyi5lH/w3n3LzIaq/iXfVsKV0PU2qDLWb+KoCvesUPAjhIqDsM4F8mgi5AbWYTM+AlGYo1WM6/YwlmDDTxxv12q+zPtFm18s5xGzZjPVeMrxy7+vxqa0vkuh5O0nfteyGlaDL3N9hsoNHI698xKltuw/6ExOxuVhXr26CpAys7jUMx7zh/p4Ky4ZSaMLiqeL759NkSilNe6lhKWjpYHteRmmMMt+o+yqwK1etnEyRb1yjv25REG4png/3r7UvwibNvwZfe/Cx8+OCnBW1eNaeMG5MYiu+1OBXQkYRCRNsQ0dTbf7KHaCY8iZJGeeua066Zh9OvnZfVXytbQqlWeZk/u6XyMhPw6k0jVlk13vaTa/D5c26Pni/2qKjh5VXaUOqpvFTqFVllUiWh+DCTekCCcNnGzWPY6wvn48K7llq0qN/cGAK7n2YdCcWovGp4edlxKHa/kjFbyuVl9ztexLy8cm0oAw2qVAlt1aG9MUhW6jAUNZ79d7Rig/LYXLi62iGjapFl/pxsxpLFUIioQUTvJaK/EdEjAO4FsERHtX+XiPbpLZlTAERRacCkXpFWmPZAGGvlK4aKvco7lHTt68yHl7MJlWozTypyVF4ZA/m2BWtw9vXyDox2WR0bSlO7DdeOQ2nbEorCaKuNl377kkobio9YUkvpOc5buRGtNuMHlqonlqQyBvtWS6N8b+JQpEnLbsNWFxKReM8dZh8KEDpPhDRKMKlXGkSVRmtzts6GZaoPn6GUf2+OpLqpSmoptWdrGeyrcl2oe41cCeUyAHsB+DyAJzLzk5n58QAOBjALwHFEdHiPaJwSUKuviIQyFt//3f7OWzH9gYCxiFHeP47vS1FKOIW7aLdGm25n1ca0hMLMtSKOTRs5gY3mqEnaKJ9xb44akMOPcOWGESzW+9rbWy/75PhdFRuDBWqPkIamUNfQkasyssdAIaHUcErIlX5LOkNJTnrezYjbcCfDLsfJos1592GG4ECzWkKp82yk63zaADuy3a3TiCxEJLTbaiO95x5zYVHm2ASLslpkdx25NpTXaldeB8y8CsAfAfyRiMafHXAKQ0UBy+fMpCmtMO2BNdZuZxuvK1eRVoJGCZJRPjc9Sa79z2lOuObrf70bp10zDw98600Bs5VtKKoRabXtk27n4RroIFLe9vKS3okdr1CVUsXo5sP9UIRJV1iVliqvCOGRlbndXp0dG+tGykv1CgnFoi2m8upkIZMTi1Sq4tLt2y7mVSy70y2dfXrtsVBEtntNFlsDZy6GhjwbjCuhlPVstNoMQsm8eo0sCUViJp3UeTSjQSpK/e7F64JzZjBVqbxiH6eE0czAxth5J4iPw7IUco3yTpkwKf/quvm633qMTJpMYitAIuSrvJxkemUcikTeQELl5dNnQlaCCU+goVFIKGVZ4eWV+dE7gY114lD0dXUi5TlSS3qnkg2IuTMHJNlNVj7ONspTDQmlJtE5m6v5T7LcybG6/RZzIME+sm4YP7p4jrJzGTq8jvf6wvl4jw6UnAjUMsoT0YFE9CciupmIbieiO4gobmXdgkBEuG/ZerzpxKuCc2YHNUllYb/g0VY7++PKN8rL5a5KJSxLtllxvsrjpFOYdqXJMRY02Kih8nIkFLYlFAU/0WFR15ss/GOjHsvx8pIkFDPBn3bNQ7jgzqXhRcGNhHTm7Idi+qkTKc/WIojBxTMyApEfe1JEbNuyQAeDQ7yfyBioat124KiSUYpnVIPmkbE2TrjYdX+Wrvd5ZDEWCtVrvE9mgLzZ+nsX3o8TLr4fdyxaWzwMqYXZD/Us3jtAXS+vXwM4DcA7ALwFwD/p3y0eqcWjUXlJKzRn4rCD6SqQO7Arvby4bKPTvVmibdtlNeuX5yzGp3/lbMPy9URqlZ61H4ontaVUJrYNxT/t09coJBRvwhOeihS8aS5bsWEEHz3zJscdWzcUPSwYSiK41sB02UpMPj4UQ7EkIqNia7exeazlOGbEbCidDDtpURFIKJnfiGGgOTaUXCZl4zc3PIzz73AXApJdJGZDyWHwav+exLlIHxONunEoy5n53J5QMsWRcuksGIpolHcZSu77jnlt+JfnxKHkqgb8vqPnxWtS9cOT0uMs3IaDNBYhIzZHDcpPX+8mhyyVOdKVKS+vmIRSJ/WKvx2xjU2jLewUv9S51lC5abTazTUYU5m6e4eBEaEFxqqNI/i3n1+P6+eVq1879YrTbwdKLzuuZmikhZvmrw6/BXZ/422VEoqN1MZsdebldUOhtl9q1i9qeguRVJfthO6QLPvuZGa8BuozlK8S0c8BXAJgsylk5nO6StUURJqhsK4TnvPTJ+SO06oVR5ErKdKifZmvO8/tO3peWn0JV6XmrVSZ5IIZ216XCPlxKLaEYrkNSzdsG+VjMTAG5r1XeYPZkIzyNm0pOO9W/26MxBgtWLUp2k/OaPCzDRtp7ONn3RLUJaXzStJbhZUbNuPoc+7Af7/u6UXZF/90B865ZRG2nuaGvuXuh2LbUOzvuJlkKPlEjwhZyMVvxCsqbCgJSdmg3U4z5lyPt16jLkM5EsAzAQwCME+RoRI5btFIicojmSqvsTpWeY2q6v738Pbn74Fzbl40LhtKJzR1o2nzQfkBYFL6jzJQW6evz1iZ+W7DKS+vVKR8y+ssakORmKzwLqqM/n4r9rG5dONmOcbo4OMvs+jOl6DsOvZ9pBZWzYZ8z3VUXidf9SAuunsZdtl2elFm9hnx46hSKsuyTpnBYKDRcL7jgQaVq2L/unySxS3ARQnFo5M8G0rqObU4rt2w38hkBzbWZSj7M/N+PaFkiiMVdJZUeVnvt46EgmLiqahmnX/78/bAt/55P5xz8yLPXsBB3Zy+46fj0kgVjQap1Cu+C2yb3XgeVbeUCrPdhq2/bfWj+bVJciLlKyZ8897DmCGJBi76L+u5FVMxDf6x+buTLAh5ubzgPLiULTHmWt+Ryst64VEp3KYxAmZLQmmSmN1avm58EorouOIdG6N8GTOWlkByvrHJtqHUNcrPIqJ9e0LJFEfqQzLvUFR5VRjlc/c5iPddnt9+q0ExyK7bY0xsL7VKzJxQTC1pQo3ZUIgoe095Xw3oM1q7hZQNxVdJxbYuTj2mlMqrUpIQFgsxlVcKOW/FnsgYaQkltujqZPxJTgsSbYqu1NizbCjkJoccFLbXLtvOp3WkFUqHEs3+OCo95qoXfO22nKTTb3uS+UlthvJyALcS0X2PNbdh+0OKvVjJbbjKKF/1sVQNbMdAS+VHnVKpVCE39Yp7TaI97+SaTSP4/Y0Lg3oxo/xdi9dGV/8NUqqWvKBN611w6DZsd5GKlI9JKDm2EFNiTj2ybjjIJhBmrvUZFePXs+dj5tF/w9CIqnvLw2swb8VGAGq3wZxEoFkqL69eSvUb27GxzqrZyBCjGQylkOIT6k6l8rICGyOu4eF1WeQCkCWUnDbLxUX1tW2Of2M5WwV0y8OzCnUZyhsA7APgdXgMuw3HXo6k8goi5b1LY3tgtKVZLjx0P3bLy76Xw8dmONP0Ki+pdvCOP/mbW3HtAyuDcxyZIN5x0nVYtVGeIEl7eWWlr2D37zKwMVzpOhJKRRyKsd/nxcJw0cYj64Zx0LcuwW9uWODSWbGvSrsN/PjSuQCAlRuVFWBotIVXfe9yAMB+x1zopOiI0lJZw/OGY05OwtKe8j5DyoWr8pJRSk5ljYP32SWoU6Re8SLl0xJKPtF52y+Hz6FcNFZLFykPUYLl5RWptGmku1tXxFCLoTDzfPMPwEYAD+u/t3jYonLMM6TKKC+tMv75p9eK+a6qJJRiUyfrfIPKcluNU/eDrqpvnx9syvYDt757btm64WQ9qa3YB2HiUFpZkeLl37YKQZRQEqlX/Pdfx23YFLWYcd2D8ra4gYTi248q+shF/n4o5XHSKG/v2JixapZgrrMn6XisVTgRD3gMT9lQ2sU4sQlLMcc6yJdQvIWBz1ASLP6kKx7Axfcsi7dd4fEWc9roNnKzDb+YiC4nonOI6HlEdCeAOwEsI6I39JbEqYGG84HEGEpYFnN3tbFJeNlVKw4A+OV18/DHm0vVka3ysvtLxTxIqKO2GBxoRK9JtWdgU+urg3LQqCGhBFsAG6ZrMV+DwYTKy3+GpmotL6824+b5q0U6l60bxh3WNrB17W7dBHuLoJRzCnU1l1f1JO2/PwDO1s2Aegdj7TJtieN40YzfSy2jfGYeNb9Ff9GY6vK82xbj8+fcEWnXdjCRG9k4QRJKrpfXjwF8AWrf9ksBvJGZZxHRMwGcDeCCHtE3ZWCvzFIqr6pswNL73jAyhh22dnNr5viVf+Uvd0VpLPrz2mgxo1GRfkJcWXure4PBhMqrUL8FHlpyv/6KTTon9dHM9PKyq7TadpuhZNS0JZSKOBQjoeTZx8p7XLRG3gfjo2feHKXbHHeDpzADc5atx2CzgZm7bCPWUX2VYzG1qG825MDGOjDNZ+UmK37LurKEUqrqfLfhGGoZ5TMklAbJqkv1W/2tp8AsfztX3r+8+FtatPYCuSqvAWa+kJl/D2ApM88CAGa+t3ekTS04Inxk/IgqL8Gg6kPy0ElNrkBkQqGQVnuwAbl7Lwgr68jfhQ1ForH4jT8DSX2TkwfJoFYuL7tfSUKJqE6qsg03Il5eqfuoM2Hdsci3s3VHQmEwDj3hysL2IsF3V02pvBoREaUTiSpn2wNJ5eWrsQxDMe/TtqKkdnA0d33ebYvxkHZ2iCFnr/jBZiPDhtLZe3W2Gdd/Lli1Ce//xfVFuZ+puFfIlVDst+svqyZO/p5E2KJ+TL3SFPzwA/23cKnEUIrvyauf9rIpxXp7Mrf7zMp5JZUJgxbItaGkjw1Sk21UQqF8CcW+MRUo5q4MYxNTsL1rxG045trslHXwtSxb54bfxdrYYat6O0jk0MKeiJuSUGJjsxMbij1OY3SaYvu5+4b2QuXVoYTyibNvwWCTMOfYN0XrDmVsXDet2YhmUjBjt1NHLDfbsPr145ImSk2aK6HsT0TriGg9gOcS0Xrr+DER6Jij8pIyT+TEJkgGs1jiu9S4MBTazI/ZHUx5xusqCSX+AYvtecf+Pa3ZNIJ9v3IBrn9opXgeiNNt0te3ufqjsc86kfJGQomoTsKVpXvsp9CIXef30Sna7E6M//KCJ6HZIDxtV1ltFUMOJa6XVzrFfldzebVKV9/o9ez8AJBVXss3bC4i7+2zqXux353kxXX4z2fjRxfPAZC3E6qyNcoSbJuFG6kBWwUa+wYmyGs4ez+UJjNvz8zbMfOA/jXHW/TGWgZ5RnnBhpJhUJWinGOuhHYOK6l/IDR0uxJK/laxsTJ7cEo2lKGRFn5x9UNRUd5v/pYFa7BppIWbH1aqHclxIOVZV+6CKFax6Gbn70LlhfBZ2+qQwG3Yu5+YhCLNEG6VzryM/Al2m+kDePneu2RvoCbTklevMg5FlC5rkQWgnMQlqb9sN3xvvqGdASxZM4Qn7jADQLghWBxpoq+eu6JIWZ8jHQ82w/vwU650uthwPBZ1E/576sZCJgdZKi8i+nTqPDP/oDvkTF3kSCiSUTJHDSLbUNzf1PUGhkTXhsJOG3nxGmEdp8xRMWiVl0XZlXOW4+t/vTtOc2SFLzRfIMYIbYZiG18l+I4FqUj5VOoVn0FK2/rG7sMt6+wjZw4n+dwEmW7veWPBbrYqUr7cD0WmtQrGxmHed6MRf0rSqjy0oTCWrh3GS/baxWkfqFB51cjam/PcB5sNjIy533n5jcuLxzr9m0ujtsQJklBybSjb6d9nAHghAJPC/i0Aruw2UVMR9neUVHn5q5AMLy/JpS/mm55UeRUSSmlFYXbbqOsNJV1nn5YkFN+gGjNGFnQH/edLKIRykqu6N/usnQ5c+hjd1Cs+fe6xtMeJVE/1ZT3HjlUc/vMjvWtlvXZy+vdjp5IMxW6T7IVG/Rs1Xl4DjUY8DkWIvRjwDO2tNmPZ+s3YTUsocCSUxOKjBs05HmnTmg1s8PswEkoXvLz8RVGVmrZXyGIozPw1ACCiCwE8n5nX6+NjAPy+Z9RNIeRIKEA4EEOGEl4rqbzK1ZdfHu9b+jwY7mCqs1WsDcmTBLAYil23Ih7Db93/rqXHe+Z1cvwskZVLq2KGdL3dQu8aR3VSJ1K+SA7p9peKQ/HpGQ9M+pleGF7DDLnxutE4lBqMrghsNBJKoj/pG/GljuXrN6PV5lLlZZ3rVuqVPJVXIxhH5jhnx8YUbDtX1Ct0gkSUuqlX9gRgbyc3AmBm16iZwrCHXmziksT7HJWV5CNeJoxLT8Y2CqbnqbzgTKQ5DCUssz8Gx6tmIJRQAqYVMMUI3UL7Bhsjhk+THBLIuDfrtK8K9Cs0I5Hy0kcfk1Cq5ofxrEhtNBpGQglbnJZwmsiZwHxnh9SqHpCN8h0FNhoJpdmIPidfZWTq21ild7983DbTFIWZkfL+ozxr9sPRulkqrwFJHa5/TQqgylZk2Eb52CfQg7WGiLoM5VcArieiY4joqwBmAzij+2RNPdgfUsz4Ka0CciaZlFE+x3PIQOAngcIhz204rOO4cVrl0wQbShh7E2+fOZSscge/mQ/M3L9h8xjuXbrOpbvVLuIEfBoDG0pMQrHKpUnbRGHXtaF0qoaQstbGMi6Pttt49u7bi+3kPGfbJRXozG24zm2aJspN6wTXSa/llIRinon5fu3TSQkFbnbfL/xJjlIH8iUU/z7q5PJKoW3n+dJ/hEb5iUHdXF7HQm2ytRrAGgBHMvO3e0HYVIOtmk1JKD46DWwsdaL+JKUHjETjOAMbV28ciazcXSYqqrwSk26otvMa924m17hsJgkzMXzo9Bvwhh9e5fT/3lNm4xlfusDpVwVChs/Y7tXx8rLokZ6NkWakrMA+/ODKTiBJeNI2yGai8VftJS0ZfXn9pSUU+Z46uc0xS+UVu9y3GwAhkzCrf8lhRcoObredS7e/f4+EwWYjGiCbk8srharx6dfpJepusAVmvhnAzZUVtzBQhg1FVHkFH3l43XBig556Xl62Ud6lyyDmLXXZfY/gyNNuwC8/eFAlY6yKQ6m0oQgToo3cwW8uMyqve5eu1+0zDJey9zw3ZDUbJHp5OaqTiA1Foq2UUNzyKgml029c4seSl5exQ0yL5KzKMsq3fRkXeN2+T8DDqzYVz9umQ+6nxo0aBwvjNiykMyraFdofbMoSiil1I+VTDCV/es+RNKcJqjvfk7NjCYXLZxCVdiZIRKmr8nrMwolDSe2/4BvlM0aJFGkbj0OJtyOtwlRbFj2R0X/8BfcBAJasHZIDCysllLgUFN6DW9CpysswUH+lGdcjc1G/zSy4A5d/O3vKOytAgaEINpTRVhvH/T3MTMTO3+NfkQKKIUvbINtb30rIcxsOmSARMG0gbDNmlO/kLh27VUUd9701xDpFjFa2yiufEebEdg02w/RAxaKxHd5HHUiJTn1MVaP8YxaOl1dixVTFAKRBKuUCKgdItRrFwKy+Um64MRvKYp2oMJZNNrZl7bSB0MOpzp7oqT6rYK7yI56rtow1Wwb7thNftTPvuDdjh60GwawYxOwHV8o2FGEL4L/evhhXz10R0mAzp5puvsGNFLTKyQeNHWJQmPwVLTldccAEjZuyD0IY1e6rXKtgWjWPOTUyJLVwGCmvJRShoVSkvMqkUEWtQq4NJTY3FF5enS4wKiRou69eY0oxFCLakYj+QET3EtE9RPQSInocEV1ERHP07066LhHRiUQ0V+8e+fxe0ua6DcszQY6YLJ33JZTUAMmTUHw9Mot/2zArzs2jLbFObMtayW04zLCcvocO+UnxTqR0GxIMHQPearFQnVh3UTArPVGfeMkcvOvkWUU0/5fe/KzCg0raAnh41B0jm8daWL5+c1ckFP860sGd/sRmjgcjE2dO774a10go0urellAcx5AObrNQVSUi5Yv3Zp33x34rsKFYKq+kDcVnpQlacxjKgKDy0teN2yjPlh0w0saUSb1CRB8lolOI6N1E9Fci+o8e0vMjABcw8zMB7A/gHgBHA7iEmfcBcIk+BoA3Qu0euQ+AowCc1EO6vMDGeL3KfFIc1hn2JBTXTRXiueS+FN6xLVHFJBQzOQ6PtitdP+0PSDLKBxKKvzLzJ0SRomoUXl6ZGyUZOgaaDS/5IOPqOSvwwPIyq2xhn9HuuPNXbgIAPLh8Q9Enef2vGx7DsM7q6j+Dj/zqJrzw2Iu75OXlPsOGdp0ONgLTAzWWby3PbdidWBkmf1pYN+aQVec2zTN1kpHGJE7PbuC3YZ8r7YslqlVe1fTGnFh8TGuGAZrdcxsO0whJdE4EcozyrwHwLgBXMfPLiehnvSCEiLYH8AoAHwAAZh4BMEJEbwPwKl3tDACXA/gcgLcB+CWrJzVLSze7MfOSntBnDcWkUb6iHT+VBSBIKIlJJ9V+0a7vMmhdFKO9kFDGWhEbit2ewFAsyqpUHM6KN1kzDTNJ5Br1TelAw/WIYgCHnzrbbVs/xIb2CDOZfFfruAZ7MjISyg8uuh+/vWEBrjn6NYHnz+X3mb0pxn/z/kZLRGq17b9bw9RiG0nlTZi+hJJWeUnoxMOoDrP1qzaIgmDBwihPbr1om8J3CgCnXPkgVm0qQ/FS0smMwUYhqaZyecViznJhzylR+2FHLddHDkNZycxMRN/Rx5uTtTvH0wAsB3AaEe0P4CYAnwTwBMMkmHkJET1e198DgL0Z90Jd5jAUIjoKSoLBnnvu2TFxOckh/VTxcp3w5frqEVcdk89R/DxKBvagjydZVL+L1w5jRyENekzlVcSh2BKKF9joS2U+BZ0Odl9CsPuTUEoo5D4HqX4hoSjVxLZ6A7TlG0Z03xZDsSQAs2lWbKJxu+3OZ94gOYW/eQ+x4MbsXF7ONQAiKi9AnhQ7mShLySKlximW5U5fDQLMEq1UeYUekKlcXjHbz7Hn3+Mcp+K6BhsNDOudP6YNhG7D5fYJjP8486YiCLMuVLuytFb21VHTtZHDUH4EAMx8nj4+p4e0PB/AJ5h5NhH9CKV6S4I0GoLHxswnAzgZAA488MCOH6ttwEtJKDYF0kcuqry8zW98nbVzLmMSCGwojroqYv/Rv7GIYD9Tr8GA5OUlOBL4q9yCVsTtOlUo7Ry+UV6GoXuw0fByk4VXmBaNR9hmzfQNw2g6DCUcirGJxs5z1i29NmkvL3+sGO+jcUko8MYru/nTXEIiKq/M+5zWbBQTfuob8MtDlRfBn2ClGK20UT6P3SftJ1bzAw3JbdhIJsDf71ya0ZuMdrt8FlX2w16j0oZidmUkol308RU9omUhgIXMbHQPf4BiMMuIaDdNw24AHrHqP9m6/kkAFveINteGUqFSMZCNfuFA9RlKKtVHalwUBtHAbdiSUCK5vKrGmyuhlH9vNdgMdOc+0/JVgSGT7AxmQvDnhaq4hYEmIeYGbVCsaEmpvEzw6aLVm4I+BwW33NhEY28X262PXLkNh+PSMLWoDSWjbSn1j53uxgZFGs25zWfttn1tiU0QUEo6NApJR/CATG3lIy38JOQG4U4bkHZsdH87hc38pLx0wMSpvOp4ef2iZ1QAYOalABYQ0dvFEZUAACAASURBVDN00SEA7obKbHyELjsCwF/03+cCeL/29noxgLW9sp8AmalXPAOmpBbwddKA2p4ztsKvk3olBnt+tye6Bas24Q0/vBIPrdhYqed2aLLamzGt6WaZRbg6Vzpe+f4YnUfxNqxJ3+1Prl94eTUaAQ0+SpdkRZ/JCG3Uk/Z4ULm0ymvnLFuP7/7jPpEGe7OmbkkoMZXXaKVRXm7Pd20ObShluhsbKn29i1/Nml9IdSmYvVSClCGJiV3ybGL2vlVLdWb/AvH4HNV23vtJbVhn34q0s2k57sc3EOzv69GUy6tTZ5w6+ASAXxPR7QAOAPAtAMcBOJSI5gA4VB8DwPkAHgQwF8ApAD7WS8LsCSOmzlDqgfJ4tx1nBHV8rxlV5k40bBvAheuB9Mvwz8XiUE67Zh7uXboev541v5qhJCUUN/4gcBuGF1wp2Fg6ge3aG3QowPQzmCWhqF+j8jK78pnr7BU6wZ2cPvOH26Pt2cb6bn3jJpeX/w4Lt+GYysuiYMGqTWW5PUF79dj0Jxrlw8l/1cYR3LFobeU9NAX6q1Cu8N3r7PHguw3bX0fsuQD6PjLIMd/Tew4K7bP2QkfyhqxSU+WibZFaSm3+NzgxHKUOQ+k5Rcx8KzMfyMzPZebDmHk1M69k5kOYeR/9u0rXZWb+T2bei5n3Y+Ybe0lbjoQC68Ue+JSd8KGXP1WqIg6gIUvtFbNXmOurEPjiOzaU8u87F6sPfd7KTZVBdrH9ULYarJZQ1LcpSyjmfCco1VJueTywUUsozYaj+hNtKJ7bsEngae7NnrSIXDvFdEEiMAbgkVZvVF7Gy8tuc9TK2CvC6v7g4y8T9+XwvRKZtQ0lFofS4T0Y6SZYG6RsGZEJWZRQEI6V1PbVMaO8D1Nnvz12wFN3cbdgljzKJPf7VD+S48Dn3vDMgAbfnhRTr/UadXJ5TYSEMmXh5PJK6OjNB/2W/XcXdeuxsbN5tAVo7yp3d8S862H1HUgoES+v5euVw969S9dVTm6x4MgZg41gIgkZLicZTucqL/Wbr/JSv/5qWJRQLLdhZmCTVnkZ+1DTk1DsYyktSUMbim1JVNqrvBMYm4Yf3V1KKHk2lIWrh7Dnzlu7Hnk+QwGrQMqIhBJruwqx7YNjCzBDi1TmJkfV34QZK1bdFEPJNcqbsSw1RQDO+/jLcdXc5YVU7jNrv8zHYLOBsbZrY9378ds6x7+5fkERehBVD04Vo7yFz/eMikcB7IEY9/IqB6FRQ4h1KiWUsnz95jH84aaFdgtRGmNGeXvesid7o2NvtauDs2wmEKi8UHoYXT1nhXMvNl0FPV1iKNIkofqLvR/1O+i5DUu1SwlF0Wf2rDHX2UyMiJzJSWIohuHYXl5Dwk6dncCkXlH0le0b9Vo8OaR75/fo1P/s1AmPlYQi01KaBeq9UynXVtl/+n3KXl4K5nFL9jbpPRVtC+1KKJNYSrnNCPs9aQd87FV7F3NBXZWXmDPNO75j0dpC8u3w8XcN2QyFme/sJSFTHZIY7cNeTalVa6SO8IEMj6p9O75/4X3FahgArrx/OT7z+9tw03yVNTcpoRR/+St2i4lYE44tctcyyltVZ0xrandRxm0L1uDwU2fjdzcudK71P866G1HFUO5x4d5vrDlDw0DD2z0vQYCv8jK0Nx2G4kkowos3520bygZhY7VUbEQMZNFjq/LKwMY8o/y9S9YH5W12GQ9rvZRoQ7FsaZ1IKBKkQOCCFpumSFuBUd6ql7ah5I3LVjGm0hKbT4/9d+rbi6W4icVkxtqccunrieiZUNHpe0C9y8UAzmXme5IXbiGQDH0+nNUUydHEiAzUodEWzpr9MP730rlYunY4OG+MwjnDInAbbrNeacu2Dr9cQiy/mLGhgOFEENuo+jg7NRia25RWtXI/Cr6EIklndhR+m8vnL9pQvOOUhDJiTfibBAlFUnFUodEo3Xj/dMuiotxIK7kqL+PJ5mc98OvFI+U7NzSb5+1fl2pG2keE2WV2qUj5apVXhoRi9m2JTPwGNk3/+rPrcP28VTj8xdqQn+hG4htE+lmLdMtNTpTEkiWhENHnAPwG6j6uB3CD/vtsIkoFH24xsAdMzo6Nvl69uDaimx1ttYsYhU1COntfvBd5lSUd+X1KGXHtlA9VOtY6cSgBXRWfZqdZd2OpV6L3oosHvMBGyWvPtGjchs27Me/emUC8/qWJykgQtspLes8pNUwMJjkkAHzpz6UiwUgrUS8v77alNOpc/Geu4WhySFh2kLqLBNNcnYmw/CY8MhyVFztl9lipetY5k3AhBYoilivFKlq52KPHDIVUN1LOPgJFc/mVDL07WoC6yJVQPgTg2cw8ahcS0Q8A3IXSlXeLRU5gIwBndEiGS6UWC68fbbWLPlLRtzkDI7ChtNUEMNpyP3OjfvHVGhIchmLHoRQ2FE5ssJQ2FuaK4x9/9d748WVzi2Ojtg5sKJHrC5WX5zYsZQ/w3YbNOy8lFNcobyMloVTt7pdaNcfQIHmsmfuNpkkR3NeDOt5KXWu8KnN51Z3AJC+ogkqO0S/35aq8NG2FiFKeq/LyylJ5tctn7FNpPyLzp2tDqVZ5iXyD4h5SZToXrzzaQ3eRO3rbAHYXynfT57Z42B9QNA6FyxcXN8rLL3esxUUfEsMy3VdJAoD7Yas+udxVUFiZ29lKY4htMlVIKJH7Uv2n3RZzB7vv3VK6gvr3m+5HqZUs47UooZRtK+8pt449F/kf/fRMlZcE6doqNIiSEmssCWIgoZjJiMMy+xoVhxK2R6RS03zpz3fgp5c/kE2/TWOww6kvIvnEwD3PcN+HH7dlkx3LcWauyzLKCzY1A7vE3J/dYk7a+rTcE6Js03+OE8NSckfvpwBcQkR/J6KT9b8LoNLJf6p35E0duDs2JhhKoXaSXStjCSTHBGO537b6rR4YoZdXqfKymy4YSlt9PB946Uw8b88dxTZjySFnTGtE9bkF7XaAjnQ+c7D7K20pP1PRn9eu7V1npDUDKdrZ8fJqh+/M8fLyPnGJKZgJZbRCQulI5YWYelX9pvb9sGEnKyzLfBWYyjYsGov175mz5HxwPj55yD7F32bxFcYoxcdGLHWJ5EAjeXlVSigJ2g0KhiKoFR0JxVJ5lbTpvhI9xZwfYq80asOaSiovZr6AiJ4O4CAoozxB5dK6gZnrWRAfpXA32EqopIyUENEzM0N8uaO2hNJhFFLchgKLodiqnnKFxFB1thpsim3Hgi2nNRvFJkhJlVdkRBsJIAe+njqevl79+tHwhgbfppCyoSjmEzIBR+Xl3fj4VF55k79PS8xeB8STIMb253AlFHe4FhJKB95oPj7w0pn40SVzFI2FutejEcLkWJyTV+Put6p+63p5tZkrN4pT7asy2cvLHiNaQhGkv1Q8ksQ4qGg7vC5qlJ8gjpLt5cXMbQCz/HIiOpKZT+sqVVMc8RTR7EzqcZVXeP1YqwzIGr8NJVR5SYZr222YoT7qmIvpmJODqvybyAztNGGp/Fq50rhPWzFJ+BKKZ+8AoF2XdTtezICZ1OS2SWQ4jtuwd05a+ZoJpyqYsRMbilJByfY6IO6S61MiBdoFkfJFfzIddeDkQysm3FDFJm/5ZjsAuGWyystIKOW52NbIfptlW2FZEdhoXK8syDYUd5EDpL93UeVFkROIq9EmyijfjS2Av9aFNqY8ciQUW/ggihnl4yov08dYwu3J/0D8/iW02hxIKL7bbFsznVgchCSqF6D0gE0Z5f22U/BpK+NQwv4AIRjTMspXQ9VpEolShe/kVWWQbhQ2lLSEkrv7pEuLLKGYZx5rMxZg6qer91VgiKhzYxtsxUDW7FNKKPkqL3Oq3WbstoPKm/fs3bd3GUrh5RXSmLKhSO790ndv2k+pAO3+7TZzNBFRL6+K68I4lMquuoIsCUUnaxRPAXhC98iZunDiUKISSvkBEEiMJo7pZke7IaFETtpuw5I6yEgolGAo9jzoqwLMFVFXxiq34VyG4jGCuIyg4CRitJ57jhRQ2FAaskrMTQ7pq9ziEs3oWJqhpHYRjF7TABpCs779IHa+OBbcWMPAQo6qvOqSLr1N/1EnnT2s39c/+4k46hVPw+47buXZUFza6sSh5AQHpnbFtL+HlFE+BVHlRXL5NtOacQlliqm8ngDg9QBWe+UE4NquUjRFkYpD+fbb98Pl9z2CWxesKV9kVEKRV11jrXbxgaVtNHHY0pGNdjt0y7T9540aTqm8YgzF3hiKMXPnrXHh/3ul7o8qV5JxPXi+OB4a5WUJRdJN2zrxnGh0U6NBJO4h40zSEZWbRHtqhz/VbiVpAWKBhoaMKEPxmJA0GdlStzlHkTbHp/JyaXD6j40dS+fVIMLuO24VtJvaDyVlQ1m2fhgrN7qb00rfZZF9mtJSg2SUz1NfC2WQpcHpgxZD8WaKiVJ55TKUvwLYlplv9U8Q0eVdpWiKQsoPZPCeg/bEbTYzQdzzJpY9dbTNRR9pCaX+qsYNbFRlxrNp2kADI2NtbUOh6B4Rtrsrs2KwxvhMVM3okgwnc/XkryhtO4fTXqHy8jb60r/R7LtO24ZZkZOuxsBxG/bOhYF2tttw9yWUmANI4eUVuV1f0i7otorvX7Ye280ot4TmRH9ph1ahtlU9Foeixk1E8jUqL3YTQko2lGJYW+dSHnULVg3hHSdd55Q9+6v/COqVRnkpl5f9t/v92bSlILIpQUI58Ck7Yd7KjZIntXTYM+R6eX0oce693SNn6sJNvSIHwvkvTVILxNKcjLXaxQCXVGqRceLWMeK9NwhbzMWqvDRYl2k5hkdbaDOSEsrmMTe9vqMfRnoFlExBjvxIeX8SKyd9rz/96zsSGBrrSSjyLpd+ckgb0kRhxkJPVF5EojW0zLQbk1Ckydtl8KddMy+oE029Mh4JRdMf2FAQX4zYecPsrtMSSnmuEwcIH2OWDcWnssoon8NQpKEqSUM/+7cX4A0/vCqRemViWEpu6pXKoZJT59EMxygvvhxy41BINlwC7gdrDINOYGNizuGSa0QRSijlhGYGnL09bNuiOTbZmp0KVRuu15i/wVZAMxIMh8djlNf9R2wY/v7tpYSSwVB0lWZDNsqnvLykuxnIVXl1MMepLYDjKq/YOAwllFDlFbSJhJdXFrUy4hJKwobC5W9MA5myoXSSiNOHHSmfQmGUF2hLXycwbqHeQIP0FgCs254clVfu8L2MiD5BRM62ZEQ0jYheQ0RnoNymd4uE/RJHhFWmeu+l+Tmm8oKqVsBMbqNt24YS5yjpj73s20a7XUoovg3FTm3eIIqqg1wJJfyAK728Yq6fNcyFvloh7jasft04lDJfmbRPjY8qt+FUHEqbOQhuNJO6NHZi7arjSlITKi9P3ROcl4+rpODk2K4ByW1Y9DyLEGRn1pXaAkoprFx8lIhJKHUYjWHKYuoVhDQ5Kq8cLy+pjMJcXgPNBhpEDpO1MaUkFABvANCCSga5mIjuJqIHAcwB8B4AJzDz6T2icUrAHqQmlbkNM6mWEkrKu6b8e1CQUCQVi0HOsAh2bLTsM4WXl0kcaE18DYp/TJstCeX2hWu8oK1Q7eDQzPHULgtWDeGzwpa5EnzJIraHhnlK/v7thcorR0JBqU6TvbysugJDCxiDrl/XhvKSvXaupNXeD8Who6AvT+UVS9vhtMksTmiqn0pSo/WTgY0xWuxfe4Fj/V0yKDNWypOxcVAnW4G04ZpEh/kzFiAcQ9TLyysbaKjo+dimXVPKbZiZhwH8FMBPiWgQwC4Ahph5TS+Jm0qwX+z6YYGhkDv444ZLV9XQ1ANhzEoOWW7iJK004jTGtGHGKE+WKGFsKLYvfqMRN8rbEspoi7F2yM4TSmnVBOKTVM5+4waxSPkwd5n6dYzylpSUY5Q3TWZFyvsqtzYH6e3Nc61KveJPIDk2FRNc6iOVZ8o+b2A5TUVhznUjDiUnsFHFg0QosjiKJA0AVSoveRyoRV5eAhCz+KvaD0V2G65uP6ry8oqVyqu04wQBotVddQV1tgAGAOiMw0t6QMuUhv1iRYYCctQqKt+R3Ja/MhxsNDDaDlOvNIkwFgyMDOlFUMEMaD27H4dii/1EcVdK24YCuDtMGnVfTo6z8SBQeelff14wZARuw/pwsIZRnkh2G7aNsKLNKpBQqqVP027qWIKyoYTlVdmGY3EWyXfFZrEUnqotoTjX6rEvjne5Ybbq2Ldoj4cgl5d1fUwaryOhpJ6xwwz0n7F9hWKQVV5hedOXUKa4yusxD/sFiiovQULJyfJKUKK3bfhNGfo6k1CgPXPCGA1X5SVHXAOuhKLaLAkxgk8qJU034CfgixnlDdN1fP5hGakzJ2lAM3WziZKgogFkLy//1RvSjYTin//mYc/BvOPeHIyZnMSODZI9CluWpCshylAqFi2x/Thq8hNR5VUrsLGwofjqJVtCMQu8sM+oyquG95ft5eU/E4r8bZDzWchziNAXkaPRmKhARh99htIB1g+PBmXm9dqDJGdlSKRWSvZeJa3EqsffgU5CMMFpFQwhlFCmNz0bSuRj8iUUhymSYSgyPYx8T64U/McRdRv27hEw2QBCqSwG8wgbVDJf+32QWUFAVjH6E7wfh5KbRiYnCSORzHjqqrykOBQfqQ226jp6SpHkMbuOhDKZJXsqr/B628nCIDYO6mwhkEq9Yg8M0Sg/HhuKUK6M8rKEMtXS1/dhQVJ5Af4kG9kCGMBvb1zgHA/o/TnMS5cklNjGOU7/MS8v7Vep5kDPhuJJKDF1UFpCUW7DcQmlOyovf2IsJJQIQ/Gjkjszypd17ffh7ylvw84c7dNkVF6BJGI2C+vIyyvNMGJMyde+5YyxFqsYpNyU+LlIx6HI19hxKDGJ0Qj+dVRedeJTUjs2uio99Stl+64LgrygNCrt1RtHkgvAXqKWDYWIDgTwRQBP0dcqbQfzc3tA25TFBtEob1YH5ZuLSSgnOZsPEQYaaqIpgg6FVWzMHdDG7jtspWlxy1vM2hOIgtX7oOc2LO3rAIQSii9lqQk7wlC6JIBLYr5UXriT2jZ5y74VM8a6batfezJW1xn1l8VQ/EBSywXc0Gfu36i8YkGa/kSdq56TYqNMWVz16l5jb2cQg1EvdZmflPZD34aSVKVav460Y9dxr6XIAsHG4ED+zRULBMltWFh02NR0qvKKLSAI6lk97xsXBecmSgFW1yj/awD/A+AO4LGxU6OB/UI2jEQkFLh2jJzJQBnCGxhtlUbjMmVGOfGpLMWMpeuGgzae8YTt8JnXPwOHPPPxYh/ttqKnQaWIXthQPJVXLEYjlFCse4BRa0VuMjEp1EGg8vJ+fcRsKDl7jpgadp/2+/Tdhu1vXG1F4Eso5rnLDKVQeXmPP8fLKxbNn1THIK7ySrH/tnZBr3KTrYuol1cC9iLG7lqMlDfSrFUvNjHXsaGMCt6SRfsCTV1xG4bMICwtbIApKaEAWM7M5/aEkkcRpJdD+i2zdZybRmOgSY7Ka6zwbS/rtNvA725cUEg3zkoHjEP3LZM+S5HjaptYwcvLVnk1CM3IwAtFaFtCoeRK8hNn34KVG0fkhmsgnhxSVi/52xabo7puwwa2xJjaU37UcxtW/atfE9gY332yQwlFTFzotu3Dj6/J8fIyaXekJuu6Ddso41DCzqMqLy7T6cQCTQOVVwaJdby8RsfChZlEh0EnNpRmw32/sXuwbSg+JsqGUpehfJWIfg619W+RipOZz+kqVY9CKDuCLaHEPabc69RENWZLKPojsFUzbWZc98DKPFqCyYyLVbRvQ5nuuA0TIhs2BhJKqOvmqE64G8zE0Oceu78GpcrLtaGY8jy34VCd5thQGvIEBiiVZcDk9K9hzDHVVhgpnzeGpAmjSuUV5vJyaRWvYYjc5AMvnTkuCcUPvHX7jKlSQwnEbguwJJhCQqkmso4NZbTVRrMR2xJZWoBYNpRMlVeD3KgYAkUXtbl58XqFukb5IwEcABU5/xb975+6TdRURmwuUnYEK/UK5afNUCqvdmlDMW6qjj99qGYyqFp8tNqlk0BoQ+nMy8uhxUhnPV4EZUso+tem0U4OmauKVG2XZQNRJuK2N9pqC55nqnPj5eUbyksbintdbmCjFM1fpfKKx6GkX6TkNnzMW589DvkknssrVga4LsWueqn82zBVacfGGOp4eY222oUK1W/bZXLq1xmTmalXtp7mrvvNXONDBTbGntXESCh1Gcr+zHwgMx/BzEfqfx/sCWVTFLEP3Og1bRtK7r7bSuVVBgaacWZLKFUZex1aBP09AU4cSpEc0jJAJuNQRuORw0Z322uxOnQbluuZjyfcU14hK329/rUlCdthwffy+ugr9yqORz0bCiFktrFEl53k8mpQZK+OCgnFXyFnBTYi/tzHZ0NxabARN81ZKq+IOrLcrySfljoqr5FWu1iUpZ6bYWh2napEoepCwh//4yXYQ+/1YiDbUEiU8Kpo6ybqMpRZRLRvTyh5lCDGJEpPp/I4x7WSoNKdjLbawWCwJ/c2x1cZfqnfa0vbUJRboWYoEaP8jIjOaziR1NBkCeh1viB/YiziULx3YsgI9u/meAyFD8mDzGbwvg3liJfOxLH//BwAejtn78vylwMx1VZHNpQGiWqaUkKRrwtjPiq7UjRCnqDLZ+aWn/HBgyrbNO+wng1FZkD2sy1OR9SjEuqqvGJGfDfORv26bsPV+qkGAXs/fjt8/DV7W+3KdQlxqWeicnnVZSgvB3AbEd1HRLcT0R2J7YG3SMRVXqTdY8sRnJuRdbBpbCjuW3fchhO+N6FrpHteeeZoHauuKuXyIiLsvM00sY9UltxGDyUUs1e46kdevftPuZBQPKO8yhiQuR+KruJ4dlmXOVsAF+oq9SvFofhzR0x9589NWYGNUFvgHjTzcU65vZugBHkzq2oQITkz+893p60HIzW9NlHPBhCoXYW/U/uhAMCb9nsijnjJU5yyOnvSjI5xlAHZrZgm60oopg0nzgYkiiiNhnIIkTBRkfN1GcobAOwN4HUo7Sdv6SZBRNQkoluI6K/6+KlENJuI5hDRb4lomi6fro/n6vMzu0lHDDGpw1dr5Hp5EamV71i7HazE/CR3tT54Cya3lPHGAsrJxg9s3HlbmaGk+6Na9NXB25+/R/F3zG045uVlf1sM9VGlAk7ltssyV0IR6lqr7IDJIb5YsNvrJPWKceP91KH7OOWVKq+Y23CVyitiLYm9jzzXZ/3sao2hmJdXXOXlk/LT970AHz74aU5ZHdXdaKtdqI19JxHJUcAeBzmBjfbOoTZ90pUNougGblPVbfiISPnXx0uIhU8CuAfA9vr4O1Dp8X9DRD8D8CEAJ+nf1cy8NxG9W9d7VxfpcGAmy+iKkcKo3mwvryZhaFSQUCydve0iGdAWtOmtjrWqp0HlfdgbbBk0CNhl2+mVNEv3wMzJjcE6RSxS3T7nTwCFUd5PvcLG8SBfQon1L7mpmsnf9/KyJcPi+ui9dKDy8vo36NgoX7GaVWl8BAhSHZA3QRva60SP2yovuws39YqhQR4rUlkd92fbhlL2rwJNHYZi0WxQlShUtVW2adMrLd4I4bbXBlPVKL/R+tcC8EYAM7tFDBE9CcCbAfxcHxOA1wD4g65yBoDD9N9v08fQ5w+ZiF0jYx+nL4YS8g2Bg0XqlXhfbY+hOHfqXec/hU0jyqBebUMh7LR1XEKJGiupdyqv1Fa7sUnCl8JMWZkkM+fF6JWhHYdiG+UFjy9TpozydkvhkjJII6MfbZDLq8bq3h+bhYdTpIlOJRQQRQLuZDpygzNV3zUYCty4L6k/P/BRYhadOEIYSDaUUhUbjl379oYTji7FdcU4dMskvktEToZtGxMkoNSTUJj5+/YxEX0PQDcDHX8I4LMAttPHOwNYw8wmNH0hAKMD2QPAAk3XGBGt1fVXeDQeBeAoANhzT2fDyY4QVXmR63US24QovI6sOJS4WqTdjq8cq4zygFZ5oZw0WsWe8u7EmFoRTx9oyLtVaiJ6sQpKfdwkfLiAFYfiGOW1FYrq2VBikfIBw0DJfMbaUhyKZ5SP2lDqT25llL3HUCpsKP7rysnlBUSkE8h2p1T/7rVaQqkxhtQiK7xHyW04FdgYSCi1GEppQ3Fjl3wnDPVrj4OhDIaCYhzK9+f3sXmSVV7jTQ65NYCnVdbKABH9E4BHmPkmu1ioyhnnygLmk7Wr84G77rprN+iUy2FcU0MRvAp+HIqBL6FkawMEGhlwbChG5TV9QPZckpDyZlHJITPpq4EUTaU6wC0vbSgWQ9H/EfJVkYC7gLAZUdPlKM75Mcko7z2beLZht7xOzIy/2GlZzhgS4nvKp18kkbzSl54ZUI8p1jHKG6lToLD4q+3NFhIpsQ3acmDHoRhI9prC6cBqe/NY3EOspM206S5mbMZ0+Iv31OXyZnDAxBnl6yaHvAPlpN0EsCu6Zz95GYC3EtGbAMyAsqH8EMCORDSgpZQnAVis6y8E8GQAC4loAMAOAFZ1iZYoYu/fGMpst+FcFHEoCZWXb5+xEXh5CXVa2pXVj9EYaIYM5WV774xr5oZR+TGVl2GmvVB5pSajmN2h3A+lLDOpV1KxNjYkt+GoDcUrG2m1g2flv6O4DUWmI01rSB+gAlqVZCq34au8zFxULaFEVF4ROnLuIRWHEgNbwUWSi25Rx6ItR0KpM4pHxkIbimGodrNlJgDXKL/19GZyW2h5oVEuDL9x2HPwby9+iq4Tt8tMObdhbZ/4T5QR8q8DsDsz/7gbhDDz55n5Scw8E8C7AVzKzO8DcBmAd+pqRwD4i/77XJROAu/U9Xv+2OJeXqrc1+nmrM4GGg2dbdjryw9sHMftGVdWM6CNaLyVFXdiaP31h18sthF1j6TUanF8SE1GsWcctaHoFXuWygumbVtCcfOe+TQ2a0goPgVRLy/vkR/1iqfhFU93Je2YdKNyuMUXN2HqFSOhyPULTK//xgAAIABJREFU2iseX0dqu0Y44VZB2VCMSsvurzwI1X5xyapot6aE4i8eGgL3Mn/5THz6YIWEIoxxs3gNyynKnKacyktP1icw83z9b5Fl2+glPgfg00Q0F8pGcqouPxXAzrr80wCOngBakhOcvwUwkKc/HmySDmz0VF7WpSMtV2i1V52BDUXo0riymvFsGIqt8qpaScYlFCqyIXcbKZIKKSKisrDpMRIKITO2o1htl2Vlvi2vLty6QWAjhe8oML43XKZU9Ok9gIP32QV777qt15Z8rXrncZ8ln8mV469C5YW06qgTt2GDXC+vBgGwFjF2D/azL3attK/zEUgo+eP45ofXlDYUj49IEoovQUwfiCTPK65Tv84CRhGp/3bLYxLKlFR5QUXKv5CZb+gJNRrMfDmAy/XfDwIIQm2ZeRjAv/SSDglRLy9/0nBWnPGXSVSqvEIbSvllfPnPd0bb8OdxiULjylpKKC1MH2h4KSuiXQCollA63TAohVQcRrHmjESlB6lXWL2PPAklrvKKucWaiXOszeE07qu8IpOuf7vSzo+hJ5g555YXrqvk1i0cMwIbikhqgJhdxpT5btkSQ4l5s+UOoWaDHKN8zBvQV0FLi6bwXeXRYBDYUBrhuzT367v1VkkokvQZU+81EjaUiXLzqstQXg3gI0Q0H8p1mKCEly1+g63CcBR1GzZGea+8Yu5SKhg59UrOxCe3GV43ptU9povNo23FUJzBWSGhJOI3GL1SecXPFZOwTwsDNz+8Ghs2jzllaufKuhJKyFAC92XPXVapvNz2gjiUiOG6anU/2GwE9PsMzaClVW9+1lspG7OiUau8kEbKMQUIFwFS9ZhqL3dRYjYtE1U/Vr3Ay0toy1+91x3GUhyK35d5B350fJWEUrZpt2Wr+soTgwONqOfYVE1f/8aeUPEoQnQu0i+2WBEV9asnr1jqldjuiYD7EfgfhCyhqMmFbQllsOmucCoUoHEJJb0fSq8Qm4SXrhvGZ3/hZgSyve/qMGo3Ul4zjsiEWaZeaUcdBfxrymOzEnXLAxVYIzSI+zYcAyOhuCvlUmIOU6+4vymIirQIHRIDjzHO3DHUIM8RJLIw8tvL0b7VHcexrAeSJNHyVFIzKm0okoQiO/9MazaKmDMfU86GovExy4Yyn5nnA/hYLwibqkhJKAquCF4poYCsPeW9vpL2GvnvWJ8mNsJI3IWEIhiXY0h5eaFHNpQUYs94wapNQV2TGia222DYtvqVIuVjNpQyDkWQUDxNRMw9OHS59SSURiM6GYf5w4yEEt4XIAU2GgmlwoYSeXyFhJJhlI8xxZyU7qpNZbcrtmGIqG7b3sSbEwUvDePULp9+/ixRGtIHoYRSpfLSv44NhSzJrCxPqc8m6susy1AOFcoeE1LLjlupBHdP3GEr8bx5r76RsEpCIVIfg2RDSa2k7ZqhDSW8zqi8bC+vHJXXNw97TvH3ZHh5pRBT9SxdG26TzMw663J+Fmi/7YFGWKYrAygzNbfarpeXkQlS0qC0qgVCu0jahuIxFNa7KwpMUZ1HUB/IsKGARDE4ZqeQbSgy08kNbGySihY3OyZK7u9AyaBSgY3+bCtRcPw741p9f2uHUjValpnx5DPxWHbv8jqFwMtLyIIwPRHTMqUkFCL6Dx2D8gydZdj8ewjAYyLb8KH7PgE/evcB+PShTxfPmwEzf6VaHZcfV3XbA80GmBGkTUim0U4NEElC0Xt0FDaUsRZm+Cov4Tr744xKKGRsKD3w8kqsKGPnlq4LGUpbOw0MNBsdb7BlnCQCG4amY789dsC+u22vr3PrMLPjduzTHpMyQhtKmDomnnpFG9CtMpuZBhKKiUPJMconzvvDVrah+MdaQskcQkZzZ9xkHQnCkVDYL/r/7X15vF9Feff3+f3umpubfd9IQmIIBLKQkASEhgQkQhUVFeMCVJTWgkproVhaX+3rQt+3r7bU2moVbS2VvopWarVKUevyqiCIFkplsUFAlLCEJSS527x/nJlzZnlmzpxzf3fLne/ncz/3d+bMmXnmLPPMs04pOEm7o+mf+G27RSGhuFKTY5RnvqmTj56NV524JGvD815UlVBGSx0dK6H8A7LYk5tQxKG8BMCJQojXjxBt4wpEhHM3LPaKqOq5/t5nf5wdR7oNEwqvmL5B88UMJTEMqSW4qzKVFzQbSpyEYuto+f7kfijabFDXoUDHkpndeNXmJd7zXhuKlFDsALf+QYH2RpYSxyZv47IZxjFnlC8kFHjrrl86wygr+jelElflY45JgbWhgIdjlB8aQsOyuei/fenrS1Ve3nLJ2GwbE3OFT0KJVnlJLy9uGwbThiJpiFRBA/xaLfQt2ruZ5n0Y9z1eQvnjc9dhSkdWzr3jIRvKWCOKAiHE00KIvUKIPZYNZcQj08cbym0o8tgzQXBolzONnScrJKHoc8HJR89m+9ZftoE8sDE7zmwoTe9ko6DTXy6hxNEei09fvBUzAskqfWoMxVDs9PVKQgHMIEXAPwka6qImLwnoRz61mIDwbtClt+mLoFdobzZclZLHnVnFHhkrZUPlxbsNH/QYdhWIeHubX+XFt2EeKwkljqG0SYbCq7yKeoXKi6fNxs2/cxrLUUILQzvJI2dDySUUJw7F/U7M++suYkxjvy6h+KWocZltmIj+lohmaMcziei61pM1fuF7sTxq9QgbChUSisNQQhJKhpeuX4T3vnydcY6TjlwbyiA6200JhbMt6JORjx6Cm3olRHssylrw2VCePezG2w4NCfQPDhUTfslGVlzb6lpf1mOA158D2WTt26xL76cs821mQ+HruOnrZXuk1y0OfEb5V/719wAAf/qq9Thj7XzY8AVLFu+8Wc7aUDyMM9ZtuK3RwJAopHr9fTPGaMWpcHT3dGbOrhedvByr5/dWDgK0GQprQ1EMJcJtmABnUegENlrtAmEJZbTsm1Xdhk8QQuxXB0KIp4hoY4tpGtfwSRzOyidyRUQoVld22oTQ3udqxbFiTo/zUurSkXrVB6Qrq5rzD3FxKMzgdPK9Uoe0zegvbUdbE8DwEimUqSdCk4SNQkLJamfSQnG/XQlFlmtDzm0V8j+X9kNNbK6KQnhzgeltOJOxVdDGGuV5Jjkovdr0rjh1kO94enc7tiyfiX+751dGORGwZkEvbHBqQrtPX1mu8oqc+FQfh/v5nUcVYtyGezrb8ON3vQhTu7LpsEqCSsCv8rL86wC4Tgec27C+CZxP5aUQY+MERi9SvqpeokFEM9UBEc1CdaY0oRG7ra9CTHW18nUklMDFSnLmPhBO9dAvXVnNSPkWGeXh5hoLBUHGoszFk1Pt+TAkbSjKsM7ZJvi2XQnFZ0PJ2mk4ZUDG0Mz097yU46jCrOM2LrDRM4Y827BWFnofs3tUvIPEtKmwbvF0fObNZs43LqEmACeTAUdHaE95DmphcGhgUB7rDKWop/K35ec879T0Ke35WKtOvq/ZslT2az5Dc+LP/g8M2kZ5XkLJVXScyosx9mdtjb2XV1Vm8H8AfI+IPovsG3k1gPe1nKpxjHiVFz9BuBcWE5W9l0GMhMIa0pmXUKVeUS+WMsqHNrACzFWvP309cOdD+zGvt9j/vb3Ev96HKR3NPDir7NbF6sUBACIzUrf77CBOE+7zUzYUV5LjmI5ZRwjTUcHuz+fKzKVe8dkf/Mkh/ZKRXf+Api4k8jlqZGVze3n7Vlksjd6GXUeXKDLJjqdVPT8lHZgqr6Ke2v5ab7MMXJ++y7avnI3Ldq4yyor3Urveo9LjJJQGkcaci7KiLbddICyhXP+Dn+OEJdNx/pbh7wkVQqWvXgjxdwBeAeBXAPYBeIUQ4tMjQdh4hS9th73yUc+5bLtZQqFK0iWUBoWloRh3SFu9YUooQ4zbMMNQPC/sdRdtNsbw7KEB3HjHw3lZHaP83mvOwTXnxWfxqZJ0cEhk+mtfPi7bK61Q37h17H5NCcVdnQKcyss873MwsCdn3m3Y7FuBy3ocfKeGhJGuhjzvIDG/Qn3wki9/rDOU0PNVjizKfmHvPKqgYnHCFJvwCUkvXDUHp6wyHWDamu5GemG34XIvLyKXkdhxTXZfQHkal2cOjnwu36pGeQKwCcAsIcRfAHiOiJzEjUcyQjs2Gsfyf4wrX+E2rDOU8Fa1Ss8bUnlxnks5Q+kfZNyGubaKQv2j3XnMfLYOV7cK7ACuEOLZSabGGBgU+URk3xuf55YZKc+ry/QjxXT0eUNt2RqyofjGattF+MBGySQZCYUs+kLpdYQADhwuDMwEPquAT9XoK4+zobj3LRSAmttQBpSE4g9sNJqJeml4jvL3b9qKN56ygqVDB+ei7Ats9Kmp8jEoxmJlr2Z+BiWUrI0qX0w9VP3qPwJgO4A98vhZAH/ZUorGObxGeftYvhBlDznbApiTUMi7mRegSSiBj4774A2VV3tEHIr2O5x6xURdGwq3D7e3bmUJZSiQMZg/5r28/HQoNaWwVTcQxgTpV53yE61CMPUKa0PxG+VtDAlTQkGJhGKfUUOOYZa+OvqEG2J+uQ2l3/XyMmwowryndVOvcG0DJtNTv7jvVlWLSV9P5E84mfWjvUdatbI0Li0wa5aiKkPZKoS4FMAhIPPyAuAPFDgCEcvl1fOPWamrj0E3iDYa5R+/3o/ZNz/BKBvKwOAQBoZEZBwKL6Ho4L6/uhKKuaoLo4rKSwiBAc3Lq1TlxfThy7fFSyjFXVGp840+Pat7G1zMic+j0EaeHNJQvYTeKZg2FHhcyRlmqyPKy8tJPePWsWOFsnrqXPbjIKPy0sfrqLwiXplgEgrPwsOk0S/VDVouZNwijYjywEblxebTJMTaUIDqDkV1UPWr7yeiJuQ9J6K50H0vJwGqxqGUxWMQNLdhR0IJf/zZ9f4VpLOSbWQfmL65VpmEopPgkzo4z5zaDEX/zXR373tfjJOWz/Ke9yFjpCKfiJwMsd44lKKsSA7pX4GrOsZeLBAOQ/Hv/Bk+tmnijhXy5JAli4a8vmOUp6AruVdN59BXPumWZWlQsANTD/dzKq+i/pAwVV4xi5BQEKBrk3Lr5BIcI1XYNhTOxkpAwVCkF5vejzewcQKqvK4F8AUA84nofQC+A+D9LadqHKNsC+D8OFJCISrcg22GEkpfEpZQVBsujQ5DYeIszLYiJBTmA6zr5cXpnXV0tDXyj7DK9yGgJBTeDuIwCeXlpdXzqrx0Ly9Jm74QzSQUYUwe/nim8DFHq3587Z6N+ONzjwOAPBmmjrIM1s/ZEkpowrSeD7fZVUZfzBjcOlwalnwLAeXlNcAENmqNOV5ebjcOQhKKcz95w6PTl/rOHIbCSGFExdbcB3OPR34M+u8yCaUV6ZDKUMltWAhxPRHdDmCXLHqZEOKe1pM1fqE//6Pn9uBD528AwH34WUHZQwb4wEai8IrC3nfF7ZkTz7OPRa16sv1QwpOcIaF4xsJ5xdTNK2S6MfvquHXLMDSUqfrsCUnB5+XFqrwCLsdqgjBUXlCR8v7UK3lbEWMJSQAvXb8I37p3X0bDENDWVs2GEuM2nE+Y1ik1ZPdelksf3LtuT75624o5KwnFF4ei0s/4+uUQtKFYTyhkd+QWR7YNpaONu54wpSObmpVKLyawsczLq4qKuC4qMRQi6gJwNoBTkam6Oojov+V2vJMC+kN53dajcMKSGYHaERIKitQrh22V13BtKMzEMySKjzBTebnX2deUjYVTeXEfSgx8qy+zDj+hhWDn8orR82f1it/e9PVw6xgR2kIZ5bWKjiQSJ/lydX1STRHY6EpQHIaEwIE+08uLXUF7+lWvQYxqJUblpe5h5u6elRUqLymhyAnXmxxSOiYUtJfTNlwJpQhKLOCzofhUfUrlVTAU7XyNwEYfra1G1WXk3wE4Dpnq68MA1gKYVHEoZrQztN/8R15qQyE+OWSjREJRk3hohaSfO3X1HDQoU0soxtXV3rT0sTx9Cn4JpYU2FHNZ56mT/Q9N7O5kJ9A/5JdQHPUgIwV509drh82coRRlyoYSSg4ZkiptlHlRqfPP9w04NpRQsOyQAJ451G+0G/JY8jHBmJVwjB1IveP6fSuenx2HojONArYNJUYE5FS4vjGH1MTct2VLXT7prVsylEN9roRiuA1XsKGMR4ayRghxsRDiG/LvEgD8BiFHKHzznf2o1LHPWKiDk1CajbCEEuPaqF7COVM7cN1FW0CkbChS5RVllC/KfGosjpbaKi/jd/gDCN0fm6EJITCoGeUdlZfF+DlPpgaZ/zk6cxuK5eU1JGDZq7L/5xy/EGsXTsPc3k7Zr922izKjtzp65tCAE4cSSucDAA8/edBoJ5SJwT7D5TbzIU5Cyf7rz6rdkVCGnDp2QC8nKYQQ+rZC9z787LIjW5pnF3EgV0LxLGT168s26xoNlVfVr/5HRJQn8CGirQC+21qSxjeiAxtlgT6x+lYIvBRT5uUVikNRK6TsqLerHe3NhpRQoBnlyyPla0soNY3yoT1DbITuj83QhMjymeVuwyUTmjriYkd8e8oDfhsKrPT1CqeunoOvvP3UfKJ0FiYREoorsZg0m3Ey4Zu694kDWkO+wD2+XzXkqB0xIyQxBZ3mPLmnlsurw0rpr5OsEmTm/ZRSVrLXkEUot27KVV7MxG9voserNMtUXjw986Z1eunOaB15hlI1l9dWABcQ0c/l8TIA98jdHIUQIj5vxgSFL8FfjITSbJDzQgG8p4fdl41Q6hX7gy9ecMuGYgU2lk1ePi8RbtvW+hJK+ccvmJWrDZtJ5zs2eqLdfWoko5pnImVVXoaXl3Ai5dU4y3P2hZm8Q6N1PrOhFFDvo26X0LH38YKhEDxuwx46ij7LJ64Y12IF/Ruy3b4P9Q86z1rvX1iebjG01ZVQFIrn7M4V9o6NHDkEoFsa5XMJjNy2bHomnFEewO4RoWICweeF5Ftx6at6O2W6uo5fNYoShuLSkLcp/6vLi/iJ7ANTeucsOWRxHTd5GCofDz3cB+izHb3phSvw3OEB3HDbQ+x5n354k7ajomKmYYZiSSjIMumqa+x77qZTkfeMUaXY/N9QeTFGeQE3l5caWsx2uzZCEol93rYh6Cq/IWZxYxjliV9E5PYEq1y1NlyVV0dbw7AnmrtmqgWBsqEMOXYhR+VVVUIJqpMtupnB8nvKZ3BtKHwfU9rtLSn4MVTxdBw3EgoRbQHwkBDiQXl8AYDzADwI4N2TcedGIKybVZOMLaFwbfgM2OFcXn6jfEETGXUaZMehNIMJC7M2TFpZWioY5fdsXYaj5071MhRGIMDea84x6ig9dAxDaTYIg0Mil1C4/Uq4tji1TsGoAxKKbN8IbBRc+np5zpZRGNXbWcfNx1fvLvYkKVML6mX2hNqWSyiEMvmI4EuvriZMq/MIRq8QMsp3WgxFt/sU+9noEor5rpnjr+42zL3PrMQKW3JQdeT90eqpMjt9vS8wWRnli+tdWjh6ls2agp8/+bzTJsCr51qN2C4+CqAPAIjoNADXIPP4ehrAx0aGtAmAkMpLFugrdZ/KyFceZ0MJkmW0Q5RNMFWM8rb6JESLjip5v8z+3A/Uhi/eges/3+NCZMkh1crWiZS3FwTMBKIm8rjkkOY92f98v9Wnosvq1xoHEeGjb9hslFXJbmAHB3Z43KY5EFEeYMcR6fAT1X9k275jh9kbNhT5/DRHFjuDg969qJPLiynr7Wpn6eaGygXAqt92HIrv+7U9tny5vGx6brrsFJy7YREzgvGl8mpqUsj5AD4mhLgRwI1EdOfIkDb+YTwez8MqlVDIP/mGk0MyNOR0mZNavmIiYtyGi+s4u4f5EvJj5Ha480koZSK6z99ex6Aol850XXsfZOqVwH4oTUuPxam8fCtzU6WkkkO6NPESiglX0s3wvXfuzPdPL3P11p+Tzdh8Tgk+dHcE4lCs8iI5ZHm7IQnl6YP9xrl2xm04LKH4n0/UsK2H8ifnHY8tMt2PQ3dA5aXfetVvv+PlxUkoTEr8CC8vAJgxpQObj5qJL975Cy9dI4lYCaVJRIr57ALwde3cpNqxUUeMOsi0ofAMpberHe9/+fFGuRDhCTOfKAJSRc5QchtKlhzycD8voagtUHWUGe0zWs2PhNv3PG+Db0I7X35T1bhCHkvt1kpcqb180e42/ytcYN3xu49RX0HzEordp49yXwqfhdO7sWz2FKd/Phi1+G0b3nOjfJQU4duvo3ifdKh7FsOs3DxzgcUBI+XrcSi2vc7nsRcLWw15zgnFit+RnhjJQdUxNwvLyhyVF78iBJBlPfjgq9fLNnla+cSbfOXYRcRwEMsMPgPg34nocQAHAXwbAIhoFTK116SEKXpa5+SxEYcS+GiOntvjlPm8v4CS1CuKoch3V31vmWePZkNpbxj7YXNShc9dUYc9aTXJ3bOjaC/8Ukep2CLsR8ptWU1AKpOzzWjK6OK8a0Juw1xgo33OQMSe5zbKclPpTMaOe/BJaBwIYFVeuYRiNVGscWowlMAluvTouA33DzGp3v19xdzfkBrSvp77potFhduGY5Rn+ldNXrtno1bGj4Ebj49xjBujvBDifUR0C4CFAL4miiVpA8BbR4q48Q5TQrFXRdlxmQ1F1bPVXgKuN5GOcKS8ErlNIylB2VCyybWj2XD2sXfaivgCbbfhN5+2wvvyljVHnt9cfyEbSru1klUMpWmVKzj0yiGpOIB1i6dpE6l/Baxo4tLRcFsAl7kNc/fLsOuUSCi29Ohzm7b7VMGYtnFYp8mnkoyzz9jHAQmF8bRTfRzsH3SkKN/iDoizodjSpc9+YZ/LJTR5j429XSpIKNy94FzO7f7zsho22VYh2u4vhPi+EOILQogDWtm9Qog7Roa08Y/QykUd64wiGIjH2FHq5vJShKnXWVdRCGRuw20NQpsVEMbBXA3xdfVJa/3SGbjirGMquTOa/bkSgQ31TYYkPjuium/QZEI2M/Ld6+MXT8fLNizCR9+wWZvM/DQXNhSBF69bYPbBTAqlRnk2DkWfUFyazf1AzHMxNhQllQwMDaHLswEUR2yr3IZt6CovNXb9+aksA762Qt8ph5Bdy91B072ec8zIjfIxqVcYmnxSCTce30JrPKavHzEQ0VIi+gYR3UNEdxPR22X5LCK6mYjuk/9nynIiomuJ6H4i+gkRbRp9msvP6eI4p1K69PRVAPg8PCEGFJNtWE+ul9FEGBqSuzW2NYxzPsSk/ta/EdWez7xR9lLH2KVEjIRieXkpCcWX4NFHV3dHE3/2mo1YPKObdSW26VST36AQ+MjrNuF3zywyE/nywBltuRzFQRXPPFt69Kn8dKgo7cEh4QlsVPfQLM+N8jFuw9brrl9ieym1M6K6Tv88i6GEPMhiplSHyQckQk564fbEyY3yTqS8C14q5ccQDqy0ykfBhjJuGAqAAQDvEEKsBbANwKVEdCyAqwDcIoRYDeAWeQwALwawWv5dAuCvRpvgUFS3OvfidQtw3KJpANyHf+2ejdgtV7EdTXclGPowY7IN2xHlDVLJIQfRKVehZTYNn/87R4veno/2slc6ZjUZFYeiJBG1G+aAmebcdRs2jzlVlLokNjkkkZk+R7eJqVJbJeWqTv102H1zZZzDRDYGpmGJrlxCsdVlZLRvT9who/yKOaaNMDQxX7n7GJZmHfribP60Lqsts26IIXBwJBRDxWSeYyd0chmKqtfvqLz8DJtr076G+wT8mbMnEUMRQjyq1GdCiGcB3ANgMYBzAfytrPa3AF4mf58L4O9Ehu8DmEFEC0eV6MCHrY5nTOnAv7ztVDTI9UrSP/b2NvdcaEWhVp6hHRvzdOJUTAQq9UohoZQxFHcF5tCifTiKZq+XF1N81OwpuO3qM+T58v6qRMp7JZQAU/CDHxsbKc/YUBrMpFBuQ3EJ49rx0eNLRhil8nL27rBdqy1Y75uOL731hVg8o1ujw3//p0lvw4XTM0bBefMFJRSrbpmKyEHAUcLN5cXQxnj65apXy2bJqixLysxFV7yEMh6TQ44KiGg5gI0AfgBgvhDiUSBjOgDmyWqLAejh1g/LMrutS4joh0T0w3379rWWTuN3eGVpr1YBYPvRs/PfXAxIlMor8PJN784+TLU61CPl1Sq07B1T55sN8tY1vj+tPtsewySmd7ez2Xb9EpHsI0Lvrj7kw4OuhGKuXL1NOXXs+U1vR7XPuQ1zE6NTzW6boaOMbl36sPkaF19jo1B5mZOfWoT43Yb9NPV0tmHO1A4v3fp70dvVju/8/un4Hy/Jdp7kVJt6mZ0U0R5bGQO2cfox84zjkNqX84LjJJSmh6HEOAkAGd2FZMjTFirTaRhJjDuGQkRTAdwI4HIhxDOhqkyZ8xULIT4mhNgshNg8d+7cVpGZERCj8NdO6x/BrX+wC/N6C1GdNcpHecv4JZSNy2biExduxtXnrM3rCmQvtS8FiQ11Xrfx2Jfok2d3rkrzteeW2fvAlCFG5WV7c6mgQD2XVUj64oNQy+9ZYZBV14TbdPpw+nTrlNpQDKM8v9oOMWOfyku9o+pKuwklcdfZYMtua8nMKflvbg8X/V7OmVpiQymlxsTbdq7GFWetYa/X6b709KNxwclH5ccbZb45RY8u4Cl1p8pSUdDq9u97NHqAMkebgteGMgqz/bgKSiSidmTM5HohxOdl8a+IaKEQ4lGp0npMlj8MYKl2+RIAbnjoCCL0otovRWdbw3BvtD86zm24zgSU9U35uV1r5xd9UvbR9w0O5f2pLtYtnhYcR4eVSFKHPmlN7WyT7XoqlzCUmM8/iqHI/hXjzFVeWhxGgwD1eevkfuR1m5xJSqdMPTtOSixsKK5Kksv75HoU2ZNheAXKLSj0wDxb9aZqxxrldai8XmWL/BjVSkz6epWZl0s0qi/O1Ha5Rf/hvsrQaBDmas+fkwi62hu44izT1vOH5xyL87csxQP7MkfYoRgJhWMoPndsIgxReaS9L+B3Uqm8KHvDpc43AAAeM0lEQVTqnwBwjxDig9qpmwBcKH9fCOCLWvkF0ttrG4CnlWps5Gk1/wPcLm/mw/v4hVtw4fbl+bH9cMvTnoRpiTmXqbyyyTV3q202cMMl2/D3F2/l20Ahofg2VtI1Iz2dYWM/97HoG4vFqLzs+BoODU0SAYoPWXcb5nIitTcJZx/Pm+KUKilkmLVtKMZkxLoNh60ovIQSPq+kMYAJsIyQstQE7bOh+LZgHk7qFe69KBYOrjODfi+72v15rzg6o2DcY3chwHlsdrQ1cNyi6fnCgbOhHI5QefnuH1GcBOvbOmKyqbxOAfAGADuJ6E75dzayRJRnEtF9AM6UxwDwZQA/A3A/gL8B8NujRahu5FYIuRoCmb1kjmY8jFlF1QkQAzSVhG3Xoewl7xsYMl66bStnY8aUDnBQq0RdQrFp1T+cHimhVAls7NM8X/TTZbm8YiQU9SHvP9gHAJjWnSX5271uAS7buYrt1wc7tUZezkoobrtxfUTUMVRe7nn9fjoqL4tOBSVZAsDLNmamyPVLpxt1ChuK6ttsQ/WkM4Dv/P7pznnuWlZCkQyN22VSl/acwEarbp1ptMypJLTfD+c2rBhgbPp6H00x6fO9cSijIKGMG5WXEOI78D/7XUx9AeDSESXKA/Wi6Km9XeOnC70sRs9cJyeS3hEnoQiRTTj6BBJCnxZVH6Py6i4x9nP09hkSirsatKHmyyoSypMHMoYyUzLOjctmYuOymfjgzfcG+9KRT6S2h5jh5SWjpBm3bi59hr0QecH8XqttFw1Pmwr9AYbic+ue2tmG5w4PAADOPHa+sWXAtpWzcMfP97s2FKtfTkLRbSEGHc6eMi7UYob1pDIkFDvVu82sqk+kfikhO+FL6Ar4M063NchhKLwNjEezQSDTBMPW5WxO6vqRxniSUCYcZmqretf4yYmyxP7mIISZtrsKfCoJJaHoKq8yKKa5ZkGvX+Ul3Pp+L68MN77lZFx3UZaW3WeU942+CGwMrRJh1HlCMpRZPbwkpp5HzOZKwTiHhkmjL9+b+mknIjx+yXTc+ge73Io6rY3we6SvUJ2Fjjxlv1pcYlCFGy7Zjnvf++J8Ve6TVLmEmj6oa09YMt1oU4cKAiwzynfZ7szOQqqUHIY+vnzAygnHgdsTB/BnG4/tm4hfJNrwbW43bnJ5JfDQJyc3QM2FuVotb7/O3txmP5Z4LCWU/gERvUXv8jlTcN1Fm7F1xWw8sv+g1b4Lpc8uUxmceNRM7H8+m+R1zxfDiO25SYXKy0+HunfKwPyUZCgzprQH6QrBF8OhH3U0G3jJ+kXYs2VpsN1Qf/O0QL0yHTvXzolHzcR5m5bgxjsejlZ5LZzehfsfe85PFJAHw6pW7MdTFilvSOiS8OvftBW/fPoQ+x6rCZlT4RgBo4EdG7N+60go/DW2cweHwoZilrc1CIetuvw84VdZubnE3Ho+ZpcklHGOmT3F5BTK/8OhXEIRwWjmvJ9AmSOhQJNQAiK7eQ1h5zHz0dPZ5rXN6CgLmNQ/FqWqMLKyEl9XxxBjrLWhJjVlM3nq+X70dDS9+2777plZR0l+zI3VaP6LPRtx8qo5AEyJR5/c1yzIvOqWz3azTBtNsytYXurRz7/xhcud/vX66vnM6unAFWetwXtfti5IB+DaDXzPJ2baUnNbb1c7Vs/vZa8JTd5hdadFTy0Jhb9IvU+7rFgVHT6VV6yE4kOD4Nxcjk6vhDKZbCgTEYbKy3HPDL883IS7eEY3njnYj2elLjtOQvGX2acaDbkfihaHUgtBCaVE5aUVc/nLYhAT2Kjub6+myrHzKJl0lau8cgklYEOxoefS0t+R8zYtxjELerFu8XTuMq1tjo6wygvwqwPzFPxyDO1NwqWnr8Kh/kG2vg71vOz0IXWwbeVs45ibGF+xaQm+ctcv8eZTV+KT391rnAs9e9cZpfq77rtiXm8XvnvVTiyw0r0YtDFGeYBX3VWhrdlw3zTuM/M9+9FIDpkYyjCgi5bc/hc2QjmBAOC7V+3Ev9+7DxdedyuAOBE1FNjG2VAO9g/ikf0Ho1VepsSg2vejqySwUS8mIqyc24OLX7giL4vRv8fEoahJb1pXIUX2BSbCqO86X93HX6tPKqYkRkFmQuRuX6tQZpQHyt+dPPBTXh/D3JUh2rflgWAcETj89etPxFnHzTfKOAlxVk8HbnzLyWwbockxIEBGI/Qe6ilkOOT7oZQY4Imq0aZHy+tlvv5tJBvKBIIvItlXFpMRNGpXPa4sn/htfWtxHPJSqdabiVzl5aHd1u9+/R07zB4i3vkYt+Hn+7IVt1JRlCFGz+5LWxK6Up9U7My/ITSJMCCEJw4lrPIC/K6jtspLGZBjVsrq2dqxFApF6hW+LXV+wfQupz916KP7T847HlM62vC52x/O6I6QTu22q2A4c2/T8vRT4BKSVpFQGsR90249bxzKKKi8kg2lRYiZK2JyCqkXRCCcnr1ox19mn9NXlrFeXqyEEiBLOSr4JpUyySjmnY8JbHy+L1MbTtNUXt/4vR3e+lWC8aq4pfpUXuV9yYmeOVemOgXKEwTmyTMrTDKFhMKrx0L55XSwY5KlPnXN+VuW4SXri7T2QRsK2ZNuDZXXcBiKxyifb3SnSbpVGFczWkLxqbzi+6qLJKHUwJ+/ZoNTVlVC8aHMJbS3sy23schWmVb4yeiXTx/Kf0czFN3tlSnT8e6XHIuTVswC4J+oSvdDiZAUYlReSkLRbSh2CnWj34hn490COHCNIaFUYSgNAIOe94h5JjZ8ag9V2mntFxMDtRjwqQ5tF+gqKJNQ3Av8p6qoJP301OcoeXCrY0ORzLzRQN/gEOu1VUaTXZu1oYyhUT5JKDVw7obFOHeDmdjY9fd3H17M48yZiOA/9luvPgOv3bpM68dto5AkzJPK7ReIV3nFeF0pnHfiEm+sRixi3nl1r0OTj2IoUztbp/IqJBTr2sCluoRSVeWlKHPo0B5dVQlFVa/DUDqlS/jhfp8NRfYR3aKLurFXOkbahlIGfZM1Hepet2mJWSt5eTXcb5D18vKIIsmGMoHg8/c3yiKepy44cCuKrvaGoTaqEmn76NMaQ6nx4eZTnOdS/YWt61FS5bJQH0rlpQL2LjltZbAtjY+X1olJ4KigL+Yr8JPg2OJsKB4vL0mrYg666/Vnf2t7kEa1CZwtocy0Y3uGoWJqxSo6ZtItbWMY/Xu9vBRDaRSLriqkNSMlFJ8H53CkrlgkhtIiOIGN7LMrf6BGnibtbVk6qxsPPXnQ8fQIMS6bhldsWoK/+uYDAKqovJh2PXWrZAKI6zGMGAmlp6OJ//7A2eW9RtBru9wWJ/zX6AuNKiovW9+uYzheXrN6OtDT0cxT7+ivwZbls4I0zZJxV/qC5lO/sSVPFxM7Oq6e995WaUSiJUb5YehufJus2far6kZ5ct61KlsAjwYSQ2kRnAAyZpZRk8vy2Xx+I8A/QXz+Ladg7xNZWmxur2oONg1XnrUGdz3yNL593+MVjPK6vj78ouovct29FyqpAAKVF07vws/2HcD07vY4ZhFDW96vVR5SedX08gob5fVFB3+9j9meu2ERTnvBXFz/gwdl+/E3fM9Jy3Cofwhv2H5UXrZjTRHgV6byCvWkFmSx72UIFfi9F3Wi64v+eZWXvnUCUMdt2K3Pq7wTQ5nw8OVM0rFyTg9+45TlQfULJ/K/8ZQVmNvbme9q2OdJ967gS9BIRPm5aBuKcX3RThntdSWUKleFJJQP79mEW/c+aaQxCSFmRepLrBii2YhDqePlxdzHmG2ZfavUtmYDc3s784m7iiG9rdnAm4Oqw3Aur1BPMY4WAPdOu3XG2suriEMxy5V6UX+PqtDGZhseQ+bBITGUFoHb8tVGW7ORb2vqg63L17O+Kpjp3t0XarbcHOggE/2sJpI6gY1FnzzKPNTi+qvwgQUmn5k9HTjruAXx/UapI2W/FXT0g3W9vALqRWLq2SjzllLP3570hoPhuA2rLLzRXl4A/uHNW7GUy2ZcQYL0YTgTdW5D8cSh6O9RJRtKg3Ebrk3lyCAxlBYhJjlkDGL0n2USymwZC/LEc3YqOlfsLkNMOnkOdfW4Pk8qDlUmnzKosYUYrWI6VdyGBzyR8mUI2VBiPO/K7r8y3MYshGIxnKbU3idV3puTj57DlsckhyzLDOCzQ8Yg38LAk214ztROrJzbg0t3rKocKd8K6WskkRhKi+B8SzWfc8wL4ts/REFt5PXEc33OOXuL2irI+4oYW933XH38Mbr0Vhof1djs3f/MOuZ/u5zDkMFQ6thQwmP0prgpeQAqOWhLGQpUyv7qmCff2fO3LC2pWY4yG9eNbzkZi2aEVaHq/sdK8jp8nmq5l1eTcP2btgEAHnv2EFuXpynOhjKWSAylRXDdhus96Zj3t9+zw6GC2g9bbSqlQ73U9kY/MSDrfwh1J/tcUoiw8bSUocj/vmzEgObaWjM5ZOXARngkFD2wMXJGmdbVhjPWFvmz2j2r6FagziQ3s6cDP3v/2S2ZIMu8vE48amZpGzESqw++WJo8DqWmaphVeY0zjpIYSosQY5SPQZH11v+hGzYUTuU1NVN5Pc6qvLIPpA5DsWkMYbiieMyH3MrI30aEhJIbUyu4pdbN5RW6f/qpWJ76k3efZRy3t6n3LJqkUgy3rVZlw3XtDNXbzSXlGjnvfKpYxVBMp4oC//a7p+GeR5/100SEevLf6CExlBYhJrAxBjGTpLnDoVt/dk8moRzoc43y6mUfrJGCvIpeub5RPvsfo/JqZTpu1W+MhFKl37q5vNR7UGrgrnmf1f1tpcqrR8a22FvyjjacBIo1PJHVI64lofg87KxIecB8fqvm9WLVvF7nOp2mcSaQOEgMpVWISL0Sg3wr2kAdnaFw80FHWwNv27UaO9bMdc51dyiX4vqrNvvKv379ifh/DzxulNWd65XXkVpBjxZUb10d/smwkFCsawOkDta1oUSmZy+7z92eyb1gKNEkleKKs9Zgbm8nfv2ERXj7DXc65+0thEcKjXxRQugfFLUkFHX/67yHvkUhJ6FUygxBw4mOGR0khtIitEpCiVlN9WkbRfUN8plff/fMF7Dlb925GkNDopbx0zcR7F63ALvXmS66de0bajxVA9y+e9VO9A8MYceffrNWv7lRPqDiUCNyvbz8YzUj5ePpySUUpm0jsDEwO3/ut7Zj8Ux+7452z77nw0FPZxsuPX1VfmzvG3Ltno34++8/iHWLwpuKDRc5M2g20D84WC85pPxfJ9DStxhQ3l+6SqwKi+CyDY83JIbSIrTKOBbn5TWo/a6mupra2Yarzzm2Ml2AZpQfQRtK30A2wVVVNZRtelSGXOUVUNcUiS/jbSh1JZQiHil8TajvzYFUKnlgYyuNKBpuvXoXpnSY08uiGd24cvcxI9Kfjlxd1dbA832D9aTxYXh5+ZBvaqYznAqkEdWzB82Z2snaU0cCiaG0CJftXIUHnziAr979KwD1xfqoOBRtqevb7GhEQMa/IOraN5bJtDSXn8FLWCMFNbEGJZQKNiQFXSqpwlCKFOgMHdrvuoy7iJQfGczrjctQMBKY3dMJImDh9G7sf76/XuoVjSnVxdqF04zjtlaovGoM5l8vP9Wr+mw1Uvr6FmFaVzve9/Lj8+O62s58ZRr40vsHipOhfdJbjariuY2Yj2dqZxv2XnOOo0LTYX+orYBizCGDcq7ykgP5+IWbsWPN3GCApc5E1F4xMVCTDseEYgIby6AYyki4DY81ls/pwY/+6ExsWDoDAPJEmFWg7kvd3GI3/85puOGSbUZZo8QoXwZuT/kYdLY1coeJkUaSUFoIYxKtK6HEqLy0ZW9VlddwkAeuRYxt9tQOnH38Anz5P36Zl/lSqlfF535rO5451N+Stv7vb27H830D+NUzWYBZKIJ68cxu/PoJC7H5qIwx7Fgzz0iOyOGEJdPx9f96DH9zwWbsOmYe/te//jSKLjX5cK7Gs3s6Ma2rDc8cGqjt/NAxAkb58YQZUzryLRqmdVef5vrld1VX5bV6vuutxUkoVR4fUU1nmlE0vCQJpYXQ1Tx1n2Hh5RWIQxnQGQpvlB9ZlA+uvdnAR153olHm20muKno627Bw+vBsJgonrZiFHWvm4VB/uYTS2dbEh1+7KVfLxeCtO1fjXy8/FWceO7+SGlDdKs7G0dHWwE/efRaOmj2ltsqrbQRSr4wmYpJaKuliWlfcJms6DstFW504FB+GG9hYpe77DW3J6CExlBZC37+8vpdXNQllzYLWq38A4IuXnoIrd68xC4c594zlPg1lOCwZcyiwsQ6aDcIxNZ5RngI9IIAS6r9nIxGHMhqoMl4lfU3rrs5QhiuhcCjiUIo2q6wHqsShvHbrsvxdHk3PsMRQWggiylPMDzc5Yug7f/uu1QCA779zF7YfPbtWP2VYv3QGfnvHKqNMkVT3BW1lMsdWQ0koocDG0YRaWIQm/GyztXr3tMg2PLEYShUc7M927eztqqHykrbJjhbGQ6lnOkemRqoKLvVKCGMRtZJsKC3Gl992Kr5z/z7HZTIWMWLtpaevMvz9Rxt1X9Nmi2woI4FD/SMjodSF4r2hCZ9QzUtIx0ikXhlvOJjv2ln9W1w+J1NrnrraDQ6ui2cPZQxOJcIEqi3OiGhMmEQVJIbSYszt7cTLNy6pfX2xsVKrKGodhjv5vHT9otYQMgLYc9IyfOknj+K8E+s/u1bCt6eGARq+23CV/GITDWo/oO5A9gMfjls0HbdevStPtNoKqO0k5mubvlWzoYzPeUHHhGYoRLQbwJ8DaAL4uBDimjEmqWUYj9+5KNmRL4Qf/dGZtXTZVXH6mrk4aUV1NeDSWVPwrStPHwGKTOw5aSn2PVseZFbYUMISSt0JRmUbnmg2lCp4XkoodWMwWh1L84TM/j1vmiahVLi+rtvwaGLCMhQiagL4SwBnAngYwG1EdJMQ4j/HlrLhQQVSXX3O2jGmxEXsjnwcZspNv0Yan/yNk0aln7r4wCtOiKr3lh1H49v3PY4Tlszw1nnDtqOwoKa3m1J5TTQTynGLpuMbP90XNdkXaszxYRdT+xOZKq/4j0m3mS2e0Y1H9h8M1n/Pucfhf/7zf46qXXDCMhQAJwG4XwjxMwAgohsAnAtgQjOUZoPYbX/HA+b1dmLTshl4x4vWlFeW2HnMvEoBfQkZTj56Tul7cNEpK2q3r2KCRiuCulW4/IzVOPPY+Vi3uDwf2O51C3Hb3qewcm7PKFBWjhfMn4pH9h80jPLKBhZjqP+1F8zFslmZbecrl5+KA4cHgvVfvXkpXr15+BuWVQGNVC6fkQYRvRLAbiHEm+TxGwBsFUJcZtW7BMAlALBs2bITH3zwwVGnNSFhPOKj//4Adq2dF0yZPpEhhMDB/sHaDjKtxjOH+vGzfQfyCH6Fz/7wIWxbORtLZ8XHN402iOh2IcTmsnrj407XAycrOtxRCPExAB8DgM2bN09M7pmQMAL4zV87eqxJGFEQ0bhhJkAWYGkzEwB41ShLESOJ8eEjWQ8PA9CfxBIAvxgjWhISEhImPSYyQ7kNwGoiWkFEHQBeA+CmMaYpISEhYdJi/MiDFSGEGCCiywB8FZnb8HVCiLvHmKyEhISESYsJy1AAQAjxZQBfHms6EhISEhImtsorISEhIWEcITGUhISEhISWIDGUhISEhISWIDGUhISEhISWYMJGytcBEe0DUDdUfg6Ax1tIzkRAGvPkQBrz5MBwxnyUEKI0l/+kYijDARH9MCb1wJGENObJgTTmyYHRGHNSeSUkJCQktASJoSQkJCQktASJocTjY2NNwBggjXlyII15cmDEx5xsKAkJCQkJLUGSUBISEhISWoLEUBISEhISWoLEUCJARLuJ6KdEdD8RXTXW9LQKRHQdET1GRHdpZbOI6GYiuk/+nynLiYiulffgJ0S0aeworwciWkpE3yCie4jobiJ6uyw/ksfcRUS3EtGP5ZjfI8tXENEP5Jj/UW4BASLqlMf3y/PLx5L+4YCImkT0IyL6kjw+osdMRHuJ6D+I6E4i+qEsG9V3OzGUEhBRE8BfAngxgGMB7CGiY8eWqpbhUwB2W2VXAbhFCLEawC3yGMjGv1r+XQLgr0aJxlZiAMA7hBBrAWwDcKl8lkfymA8D2CmEWA9gA4DdRLQNwJ8A+JAc81MALpb1LwbwlBBiFYAPyXoTFW8HcI92PBnGfLoQYoMWbzK677YQIv0F/gBsB/BV7fidAN451nS1cHzLAdylHf8UwEL5eyGAn8rfHwWwh6s3Uf8AfBHAmZNlzACmALgDwFZkEdNtsjx/x5HtL7Rd/m6T9Wisaa8x1iXIJtCdAL6EbMvwI33MewHMscpG9d1OEko5FgN4SDt+WJYdqZgvhHgUAOT/ebL8iLoPUq2xEcAPcISPWap+7gTwGICbATwAYL8QYkBW0ceVj1mefxrA7NGluCX4MwBXAhiSx7Nx5I9ZAPgaEd1ORJfIslF9tyf0BlujBGLKJqOv9RFzH4hoKoAbAVwuhHiGiBtaVpUpm3BjFkIMAthARDMAfAHAWq6a/D/hx0xEvw7gMSHE7US0QxUzVY+YMUucIoT4BRHNA3AzEf1XoO6IjDlJKOV4GMBS7XgJgF+MES2jgV8R0UIAkP8fk+VHxH0gonZkzOR6IcTnZfERPWYFIcR+AN9EZj+aQURqQamPKx+zPD8dwJOjS+mwcQqAlxLRXgA3IFN7/RmO7DFDCPEL+f8xZAuHkzDK73ZiKOW4DcBq6SHSAeA1AG4aY5pGEjcBuFD+vhCZnUGVXyC9Q7YBeFqJ0hMFlIkinwBwjxDig9qpI3nMc6VkAiLqBnAGMkP1NwC8Ulazx6zuxSsBfF1IJftEgRDinUKIJUKI5ci+168LIV6HI3jMRNRDRL3qN4AXAbgLo/1uj7UhaSL8ATgbwL3IdM9XjzU9LRzXZwA8CqAf2YrlYmS641sA3Cf/z5J1CZm32wMA/gPA5rGmv8Z4X4hMrP8JgDvl39lH+JhPAPAjOea7ALxLlq8EcCuA+wF8FkCnLO+Sx/fL8yvHegzDHP8OAF860scsx/Zj+Xe3mqdG+91OqVcSEhISElqCpPJKSEhISGgJEkNJSEhISGgJEkNJSEhISGgJEkNJSEhISGgJEkNJSEhISGgJEkNJmPQgokGZoVX9LR/Bvn5MRJ+JrPvxKolIiehyIrpA/v4UEb3SOv9c4NoOIvqWFviXkFAZ6eVJSAAOCiE2+E4SUZsockDVBhGtRbaIO42IeoQQB0L1hRBvqtB2G4A3AqiVhlwI0UdEtwA4H8D1ddpISEgSSkICAyK6iIg+S0T/DOBrsuwKIrpN7h/xHq3u1ZTtl/NvRPQZIvo9T7OvBfBp2d5L5bVtss0d8vgDRPQ++fubRLRZJnf8FBHdJfe7+B2m7Z0A7ohhfET0x5o09ggRfVKe+icAr4u5PwkJHJKEkpAAdMtsvADw30KIl8vf2wGcIIR4kohehGzviJOQRRnfRESnATiALL3HRmTf0x0Abvf0cz6ydPlrAFwG4DNCiAEiugjA54jobcj2p9lqXbcBwGIhxDoAUKlULJzC9Pu/iegP7YpCiHcBeBcRTQfwbQAflqfuArDFQ3tCQikSQ0lI8Ku8bhZCqCSBL5J/P5LHU5ExmF4AXxBCPA8ARMTmeSOiLQD2CSEeJKKHAVxHRDOFEE8JIe4mok8D+Gdk+3L0WZf/DMBKIvoLAP8CKTFZWAhzMykAuEII8TmNhue034RMtfUhIcTtQJaVmIj6iKhXCPEsN46EhBCSyishwQ/dxkEAPiCy3fA2CCFWCSE+Ic/F5C/aA+AYmQH3AQDTAJynnT8ewH4A8+0LhRBPAViPLFPwpQA+zrR/EFlOqli8G8DDQohPWuWdAA5VaCchIUdiKAkJcfgqgDfKvVRARIvlvhPfAvByIuqW2V5fYl9IRA0Ar0KmPlsusiy45yJjMiCiVyBL4ncagGttlRYRzQHQEELcCOCPwBve7wGwKmYgcr+QMwG8zSqfjUyK6o9pJyHBRlJ5JSREQAjxNeml9T25IddzAF4vhLiDiP4RWebiB5HZJGycBuARIcQjWtm3ABxLREsBXANglxDiISL6MIA/R5FyHMh20vukZExAtg21ja8gM/jH4B0AFgG4VY7lJmlXOR3AlyPbSEhwkLINJyS0EET0bgDPCSH+dAz6/gKAK4UQ99W8/vMA3imE+GlrKUuYLEgqr4SEIwdXITPOV4bcPO6fEjNJGA6ShJKQkJCQ0BIkCSUhISEhoSVIDCUhISEhoSVIDCUhISEhoSVIDCUhISEhoSVIDCUhISEhoSX4/5XUoEfnsK+iAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] @@ -455,7 +454,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.6.6" }, "toc": { "base_numbering": 1, diff --git a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb index 2e7b30d6726..7c0db5b1a9b 100644 --- a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb @@ -29,7 +29,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Signal Hound sa124B (serial:17172185, firmware:Version 3.13) in 6.15s\n" + "Connected to: Signal Hound sa124B (serial:17172185, firmware:Version 3.13) in 5.92s\n" ] } ], @@ -65,11 +65,18 @@ "execution_count": 5, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1054\n" + ] + }, { "data": { "text/plain": [ - "array([-95.04801941, -90.23478699, -90.57860565, ..., -92.38912201,\n", - " -99.49388123, -96.53659058])" + "array([-91.55989838, -98.06058502, -95.64240265, ..., -91.06426239,\n", + " -91.20920563, -91.69102478])" ] }, "execution_count": 5, @@ -93,29 +100,30 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 928\n" + "Starting experimental run with id: 937\n", + "2107\n" ] }, { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 15, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -139,29 +147,30 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 929\n" + "Starting experimental run with id: 938\n", + "2107\n" ] }, { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 16, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -185,29 +194,30 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 930\n" + "Starting experimental run with id: 939\n", + "2107\n" ] }, { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 17, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -231,29 +241,30 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 932\n" + "Starting experimental run with id: 940\n", + "4215\n" ] }, { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 19, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -277,36 +288,37 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 11, "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Starting experimental run with id: 934\n" + "During call of saInitiate the followingWarning: saBandwidthClamped was raised\n" ] }, { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "During call of saInitiate the followingWarning: saBandwidthClamped was raised\n" + "Starting experimental run with id: 941\n", + "52500\n" ] }, { "data": { "text/plain": [ - "([], [None])" + "([], [None])" ] }, - "execution_count": 21, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 2b928145439..5d45c3202f5 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -947,11 +947,16 @@ def sweep(self, start, stop, step=None, num=None): step=step, num=num) -class ArrayParameter2(Parameter): +class ParameterWithSetpoints(Parameter): """ - - - + A parameter that has associated setpoints. The setpoints is nothing + more than a list of other paramameters that descripe the values, names + and units of the setpoint axis for this parameter. + + In most cases this will probably be a parameter that returns an array. + It is expected that the setpoint arrays are 1D arrays such that the + combined shape of the parameter. E.G if parameter is of shape (m,n) + self.setpoints is a list of parameters of shape (m,) and (n,) """ def __init__(self, *args, setpoints=None, **kwargs): if setpoints is None: diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index a83a6adc711..ac7525c547f 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -8,7 +8,7 @@ from qcodes.instrument.base import Instrument import qcodes.utils.validators as vals from qcodes.instrument.parameter import Parameter, ArrayParameter, \ - ArrayParameter2 + ParameterWithSetpoints log = logging.getLogger(__name__) @@ -333,7 +333,7 @@ def __init__(self, name, dll_path=None, **kwargs): unit='depends on mode', get_cmd=self._get_averaged_sweep_data, set_cmd=False, - parameter_class=ArrayParameter2, + parameter_class=ParameterWithSetpoints, vals=vals.Arrays(), setpoints=(self.frequency_axis,), snapshot_value=False) From aaa0f01b6a23fd5c0cd173e4d464854b4085f6e1 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 11 Oct 2018 14:38:12 +0200 Subject: [PATCH 109/719] use new name in measurements --- qcodes/dataset/measurements.py | 41 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index ae8d6e4e3d7..e0f8db2d557 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -12,7 +12,7 @@ import qcodes as qc from qcodes import Station from qcodes.instrument.parameter import ArrayParameter, _BaseParameter, \ - Parameter, MultiParameter, ArrayParameter2 + Parameter, MultiParameter, ParameterWithSetpoints from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.param_spec import ParamSpec from qcodes.dataset.data_set import DataSet @@ -156,10 +156,10 @@ def add_result(self, *res_tuple: res_type) -> None: self._unbundle_arrayparameter(parameter, res, found_parameters) - elif isinstance(parameter, ArrayParameter2): - self._unbundle_arrayparameter2(parameter, - res, - found_parameters) + elif isinstance(parameter, ParameterWithSetpoints): + self._unbundle_parameter_with_setpoints(parameter, + res, + found_parameters) for partial_result in res: parameter = partial_result[0] @@ -292,9 +292,10 @@ def _unbundle_arrayparameter(self, parameter.setpoints, res, found_parameters) - def _unbundle_arrayparameter2(self, parameter: ArrayParameter2, - res: List[res_type], - found_parameters: List[str]) -> None: + def _unbundle_parameter_with_setpoints(self, + parameter: ParameterWithSetpoints, + res: List[res_type], + found_parameters: List[str]) -> None: setpoint_names = [] setpoint_data = [] for setpointparam in parameter.setpoints: @@ -653,11 +654,11 @@ def register_parameter( setpoints, basis, paramtype) - elif isinstance(parameter, ArrayParameter2): - self._register_arrayparameter2(parameter, - setpoints, - basis, - paramtype) + elif isinstance(parameter, ParameterWithSetpoints): + self._register_parameter_with_setpoints(parameter, + setpoints, + basis, + paramtype) elif isinstance(parameter, MultiParameter): self._register_multiparameter(parameter, setpoints, @@ -753,14 +754,14 @@ def _register_arrayparameter(self, basis, paramtype) - def _register_arrayparameter2(self, - parameter: ArrayParameter2, - setpoints: setpoints_type, - basis: setpoints_type, - paramtype: str) -> None: + def _register_parameter_with_setpoints(self, + parameter: ParameterWithSetpoints, + setpoints: setpoints_type, + basis: setpoints_type, + paramtype: str) -> None: """ - Register an ArrayParameter2 and the setpoints belonging to the - ArrayParameter2 + Register an ParameterWithSetpoints and the setpoints belonging to the + Parameter """ name = str(parameter) my_setpoints = list(setpoints) if setpoints else [] From 3ba891e24384e26b44b01cb575d81f8b7fc01bc3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 12 Oct 2018 17:13:49 +0200 Subject: [PATCH 110/719] make setpoints a property --- qcodes/instrument/parameter.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 5d45c3202f5..0f5eff6f3d6 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -958,13 +958,25 @@ class ParameterWithSetpoints(Parameter): combined shape of the parameter. E.G if parameter is of shape (m,n) self.setpoints is a list of parameters of shape (m,) and (n,) """ - def __init__(self, *args, setpoints=None, **kwargs): + def __init__(self, *args, + setpoints: Sequence[Parameter]=None, **kwargs) -> None: if setpoints is None: - self.setpoints = [] + self._setpoints = () else: self.setpoints = setpoints super().__init__(*args, **kwargs) + @property + def setpoints(self): + return self._setpoints + + @setpoints.setter + def setpoints(self, setpoints): + for setpointarray in setpoints: + if not isinstance(setpointarray, Parameter): + raise RuntimeError + self._setpoints = setpoints + class GeneratedSetPoints(Parameter): """ From 482530d56a900335e58821ba1d8a03a3c85f5011 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 22 Oct 2018 13:52:35 +0200 Subject: [PATCH 111/719] Import ParameterWithSetpoints to main qcodes namespace --- qcodes/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/__init__.py b/qcodes/__init__.py index ceed84f6a63..f09c3ff247e 100644 --- a/qcodes/__init__.py +++ b/qcodes/__init__.py @@ -62,6 +62,7 @@ Parameter, ArrayParameter, MultiParameter, + ParameterWithSetpoints, StandardParameter, ManualParameter, ScaledParameter, From 81c407a8b7236547e4c7c9ab584badc3c8fc97ab Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 22 Oct 2018 13:53:02 +0200 Subject: [PATCH 112/719] Add ParameterWithSetpoints to docs --- docs/api/public.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/public.rst b/docs/api/public.rst index 302e6ae104e..ca634cef9cb 100644 --- a/docs/api/public.rst +++ b/docs/api/public.rst @@ -107,7 +107,7 @@ Instrument Function Parameter - StandardParameter + ParameterWithSetpoints ArrayParameter MultiParameter ManualParameter From 1fd85af2f98766d2c839826988e82e7228e261a3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 22 Oct 2018 13:53:33 +0200 Subject: [PATCH 113/719] Add link to parameter from ParameterWithSetpoints --- qcodes/instrument/parameter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 0f5eff6f3d6..6df6baef8ca 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -957,6 +957,9 @@ class ParameterWithSetpoints(Parameter): It is expected that the setpoint arrays are 1D arrays such that the combined shape of the parameter. E.G if parameter is of shape (m,n) self.setpoints is a list of parameters of shape (m,) and (n,) + + In all other ways this is identical to :class:`Parameter` See the + documentation of :class:`Parameter` for more details. """ def __init__(self, *args, setpoints: Sequence[Parameter]=None, **kwargs) -> None: From ce2d7e28711555c7cb302829c05f14bf37868c4c Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 22 Oct 2018 13:53:57 +0200 Subject: [PATCH 114/719] add title to notebook --- ... with Signal Hound USB-SA124B new Array Parameter.ipynb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb index 7c0db5b1a9b..38287c9bb69 100644 --- a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb @@ -1,5 +1,12 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Qcodes example with Signal Hound USB-SA124B new Array Parameter" + ] + }, { "cell_type": "code", "execution_count": 1, From 31d9c4b887194d31b84f00328bc731bafca5e5b0 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 22 Oct 2018 14:39:32 +0200 Subject: [PATCH 115/719] Make sure that database exists --- ...Simple Example of new ArrayParameter.ipynb | 504 ---------------- ...xample of new ParameterWithSetpoints.ipynb | 536 ++++++++++++++++++ 2 files changed, 536 insertions(+), 504 deletions(-) delete mode 100644 docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb create mode 100644 docs/examples/DataSet/Simple Example of new ParameterWithSetpoints.ipynb diff --git a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb b/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb deleted file mode 100644 index 32d14da0704..00000000000 --- a/docs/examples/DataSet/Simple Example of new ArrayParameter.ipynb +++ /dev/null @@ -1,504 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Simple Example of ParameterWithSetpoints\n", - "This notebook has an example of a new simpler ArrayParameter replacement\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.instrument.parameter import Parameter, _BaseParameter" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from typing import Optional, Union, Iterable, Callable\n", - "Number = Union[float, int]\n", - "from qcodes.utils.validators import Validator" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.utils.validators import Numbers\n", - "from qcodes.instrument.base import Instrument\n", - "from qcodes.dataset.measurements import Measurement" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.instrument.parameter import ParameterWithSetpoints, GeneratedSetPoints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we define an dummy instrument that returns something like a frequency spectrum from `f_start` to `f_stop`\n", - "in `n_points` steps. The functionality of the ArrayParameter is implemented only by having a reference to it's setpoints which is consumed by the dataset context manager. To do this we only have to define the parameter for the setpoints and the spectrum and let the parameter know that the frequency axis is the setpoints " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "class DummyArray(ParameterWithSetpoints):\n", - " \n", - " def get_raw(self):\n", - " npoints = self.root_instrument.n_points()\n", - " return np.random.rand(npoints)\n", - " \n", - "\n", - "class DummySpectrumAnalyzer(Instrument):\n", - " \n", - " def __init__(self, name, **kwargs):\n", - " \n", - " super().__init__(name, **kwargs)\n", - " \n", - "\n", - " self.add_parameter('f_start',\n", - " initial_value=0,\n", - " unit='Hz',\n", - " label='f start',\n", - " vals=Numbers(0,1e3),\n", - " get_cmd=None,\n", - " set_cmd=None)\n", - "\n", - " self.add_parameter('f_stop',\n", - " unit='Hz',\n", - " label='f stop',\n", - " vals=Numbers(1,1e3),\n", - " get_cmd=None,\n", - " set_cmd=None)\n", - "\n", - " self.add_parameter('n_points',\n", - " unit='',\n", - " vals=Numbers(1,1e3),\n", - " get_cmd=None,\n", - " set_cmd=None)\n", - " \n", - " self.add_parameter('freq_axis',\n", - " unit='Hz',\n", - " label='Freq Axis',\n", - " parameter_class=GeneratedSetPoints,\n", - " startparam=self.f_start,\n", - " stopparam=self.f_stop,\n", - " numpointsparam=self.n_points)\n", - " \n", - " self.add_parameter('spectrum',\n", - " unit='dBm',\n", - " setpoints=(self.freq_axis,),\n", - " label='Spectrum',\n", - " parameter_class=DummyArray)\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "a = DummySpectrumAnalyzer('foobar')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we setup the limits of the spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "a.f_start(0)\n", - "a.f_stop(500)\n", - "a.n_points(501)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And we can grab the axis" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.,\n", - " 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21.,\n", - " 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32.,\n", - " 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43.,\n", - " 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,\n", - " 55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65.,\n", - " 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76.,\n", - " 77., 78., 79., 80., 81., 82., 83., 84., 85., 86., 87.,\n", - " 88., 89., 90., 91., 92., 93., 94., 95., 96., 97., 98.,\n", - " 99., 100., 101., 102., 103., 104., 105., 106., 107., 108., 109.,\n", - " 110., 111., 112., 113., 114., 115., 116., 117., 118., 119., 120.,\n", - " 121., 122., 123., 124., 125., 126., 127., 128., 129., 130., 131.,\n", - " 132., 133., 134., 135., 136., 137., 138., 139., 140., 141., 142.,\n", - " 143., 144., 145., 146., 147., 148., 149., 150., 151., 152., 153.,\n", - " 154., 155., 156., 157., 158., 159., 160., 161., 162., 163., 164.,\n", - " 165., 166., 167., 168., 169., 170., 171., 172., 173., 174., 175.,\n", - " 176., 177., 178., 179., 180., 181., 182., 183., 184., 185., 186.,\n", - " 187., 188., 189., 190., 191., 192., 193., 194., 195., 196., 197.,\n", - " 198., 199., 200., 201., 202., 203., 204., 205., 206., 207., 208.,\n", - " 209., 210., 211., 212., 213., 214., 215., 216., 217., 218., 219.,\n", - " 220., 221., 222., 223., 224., 225., 226., 227., 228., 229., 230.,\n", - " 231., 232., 233., 234., 235., 236., 237., 238., 239., 240., 241.,\n", - " 242., 243., 244., 245., 246., 247., 248., 249., 250., 251., 252.,\n", - " 253., 254., 255., 256., 257., 258., 259., 260., 261., 262., 263.,\n", - " 264., 265., 266., 267., 268., 269., 270., 271., 272., 273., 274.,\n", - " 275., 276., 277., 278., 279., 280., 281., 282., 283., 284., 285.,\n", - " 286., 287., 288., 289., 290., 291., 292., 293., 294., 295., 296.,\n", - " 297., 298., 299., 300., 301., 302., 303., 304., 305., 306., 307.,\n", - " 308., 309., 310., 311., 312., 313., 314., 315., 316., 317., 318.,\n", - " 319., 320., 321., 322., 323., 324., 325., 326., 327., 328., 329.,\n", - " 330., 331., 332., 333., 334., 335., 336., 337., 338., 339., 340.,\n", - " 341., 342., 343., 344., 345., 346., 347., 348., 349., 350., 351.,\n", - " 352., 353., 354., 355., 356., 357., 358., 359., 360., 361., 362.,\n", - " 363., 364., 365., 366., 367., 368., 369., 370., 371., 372., 373.,\n", - " 374., 375., 376., 377., 378., 379., 380., 381., 382., 383., 384.,\n", - " 385., 386., 387., 388., 389., 390., 391., 392., 393., 394., 395.,\n", - " 396., 397., 398., 399., 400., 401., 402., 403., 404., 405., 406.,\n", - " 407., 408., 409., 410., 411., 412., 413., 414., 415., 416., 417.,\n", - " 418., 419., 420., 421., 422., 423., 424., 425., 426., 427., 428.,\n", - " 429., 430., 431., 432., 433., 434., 435., 436., 437., 438., 439.,\n", - " 440., 441., 442., 443., 444., 445., 446., 447., 448., 449., 450.,\n", - " 451., 452., 453., 454., 455., 456., 457., 458., 459., 460., 461.,\n", - " 462., 463., 464., 465., 466., 467., 468., 469., 470., 471., 472.,\n", - " 473., 474., 475., 476., 477., 478., 479., 480., 481., 482., 483.,\n", - " 484., 485., 486., 487., 488., 489., 490., 491., 492., 493., 494.,\n", - " 495., 496., 497., 498., 499., 500.])" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.freq_axis()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or the spectrum" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0.37372587, 0.54861787, 0.53155288, 0.82667582, 0.94220873,\n", - " 0.0698023 , 0.89762473, 0.40402402, 0.94676787, 0.72479779,\n", - " 0.90016702, 0.50196169, 0.67613499, 0.96529924, 0.15008748,\n", - " 0.44617032, 0.77400385, 0.36104437, 0.6286802 , 0.69278277,\n", - " 0.12981568, 0.70792455, 0.63326382, 0.79600711, 0.77696625,\n", - " 0.60408452, 0.34930137, 0.33298155, 0.99237339, 0.72181006,\n", - " 0.24177301, 0.38409252, 0.13977054, 0.46336893, 0.29702444,\n", - " 0.32585009, 0.85559257, 0.506369 , 0.79234633, 0.91855242,\n", - " 0.91216349, 0.82632103, 0.15051881, 0.38302095, 0.39616307,\n", - " 0.32864887, 0.67891701, 0.01545452, 0.32810263, 0.84456954,\n", - " 0.30411356, 0.83792683, 0.18423625, 0.76232546, 0.62204577,\n", - " 0.28122632, 0.90895218, 0.47174043, 0.0835899 , 0.880365 ,\n", - " 0.09111603, 0.50584601, 0.56714919, 0.57147067, 0.85644402,\n", - " 0.22211664, 0.05509187, 0.95254653, 0.93371861, 0.97754025,\n", - " 0.0207392 , 0.28635372, 0.63367136, 0.0663695 , 0.70019442,\n", - " 0.40926177, 0.42111847, 0.85448678, 0.98820638, 0.94779916,\n", - " 0.25279355, 0.38715305, 0.30811057, 0.8744069 , 0.50608295,\n", - " 0.58995161, 0.58200316, 0.58201891, 0.93918669, 0.6899701 ,\n", - " 0.95871603, 0.14629169, 0.80691971, 0.99692501, 0.17309138,\n", - " 0.40671056, 0.87719149, 0.68771378, 0.08381251, 0.14822247,\n", - " 0.69180229, 0.03358827, 0.30626825, 0.33936864, 0.88937098,\n", - " 0.99683227, 0.7537689 , 0.35666654, 0.23870022, 0.80237453,\n", - " 0.83317602, 0.56290746, 0.4612086 , 0.59187958, 0.35496415,\n", - " 0.76680147, 0.72366515, 0.53806547, 0.73491729, 0.87097106,\n", - " 0.22250074, 0.4319 , 0.25040755, 0.4204853 , 0.57152887,\n", - " 0.67989035, 0.51488572, 0.12774031, 0.86615569, 0.78384103,\n", - " 0.04802505, 0.65392064, 0.96986131, 0.47990375, 0.3774105 ,\n", - " 0.06543123, 0.41360314, 0.1389294 , 0.23166719, 0.67111829,\n", - " 0.59806864, 0.73826979, 0.4013829 , 0.63824427, 0.44717827,\n", - " 0.15403842, 0.39021108, 0.10353845, 0.96664997, 0.41367465,\n", - " 0.22059292, 0.17918976, 0.96500464, 0.51467301, 0.89966624,\n", - " 0.93987921, 0.94166864, 0.64683108, 0.55641748, 0.9484579 ,\n", - " 0.66408577, 0.37486359, 0.65857553, 0.00120706, 0.76021654,\n", - " 0.95142316, 0.74106431, 0.3687487 , 0.81576676, 0.89905403,\n", - " 0.60252817, 0.52068992, 0.99020434, 0.01758782, 0.26871668,\n", - " 0.42934743, 0.74147531, 0.02036298, 0.90464033, 0.67078621,\n", - " 0.55625392, 0.61639495, 0.68145904, 0.18213379, 0.03731415,\n", - " 0.28217922, 0.82413099, 0.41451497, 0.06819495, 0.67933438,\n", - " 0.48485664, 0.02562523, 0.99595955, 0.8278784 , 0.56357999,\n", - " 0.45688242, 0.15482338, 0.88100967, 0.75521795, 0.66280644,\n", - " 0.43293394, 0.70636499, 0.83458264, 0.16970696, 0.47818101,\n", - " 0.08842654, 0.77442703, 0.56663918, 0.24441029, 0.55706783,\n", - " 0.08530588, 0.48254471, 0.90653557, 0.86716833, 0.92738514,\n", - " 0.29735555, 0.5957369 , 0.34662178, 0.14905592, 0.84934635,\n", - " 0.37038126, 0.91797818, 0.10743678, 0.33358987, 0.61751291,\n", - " 0.56708866, 0.96416561, 0.9008846 , 0.5365646 , 0.33294292,\n", - " 0.7055552 , 0.22700866, 0.21832081, 0.37975166, 0.69098247,\n", - " 0.10769966, 0.14557844, 0.14896331, 0.37194517, 0.45441072,\n", - " 0.83939733, 0.99817352, 0.36444098, 0.043637 , 0.19484866,\n", - " 0.39253182, 0.75448118, 0.35597998, 0.80725856, 0.95531812,\n", - " 0.79183714, 0.36342638, 0.45123011, 0.92610209, 0.25520695,\n", - " 0.85375401, 0.01310321, 0.48663791, 0.48385191, 0.8494894 ,\n", - " 0.76816717, 0.72400051, 0.0430897 , 0.15606243, 0.53290784,\n", - " 0.09257425, 0.75460404, 0.74206088, 0.61720626, 0.51084909,\n", - " 0.58411453, 0.47311666, 0.53830169, 0.9681255 , 0.79663431,\n", - " 0.57598398, 0.77865371, 0.65301602, 0.18408085, 0.80375723,\n", - " 0.23633886, 0.58244941, 0.29898102, 0.02252307, 0.98082483,\n", - " 0.23015448, 0.70841724, 0.05523285, 0.49451749, 0.35346533,\n", - " 0.85056982, 0.33981886, 0.06833761, 0.79821593, 0.11604247,\n", - " 0.8953603 , 0.46323585, 0.23137089, 0.44835628, 0.80901788,\n", - " 0.42361957, 0.51037851, 0.23792164, 0.7941132 , 0.76321701,\n", - " 0.11911182, 0.84181059, 0.60137409, 0.34603324, 0.22177182,\n", - " 0.10613795, 0.89584437, 0.64215604, 0.2739601 , 0.76154826,\n", - " 0.04708115, 0.81540537, 0.12827219, 0.01783416, 0.62473422,\n", - " 0.6454418 , 0.35580161, 0.25226381, 0.15315039, 0.06409371,\n", - " 0.82481876, 0.26274587, 0.77689317, 0.28502571, 0.11676692,\n", - " 0.21020535, 0.58340203, 0.50298104, 0.66517868, 0.91702034,\n", - " 0.41895255, 0.48976598, 0.71751388, 0.55612794, 0.79018665,\n", - " 0.08031651, 0.93057851, 0.56953056, 0.04527181, 0.88304957,\n", - " 0.70831083, 0.90265482, 0.94031171, 0.2569966 , 0.66892006,\n", - " 0.66635678, 0.27309862, 0.03279321, 0.7976703 , 0.50451827,\n", - " 0.75593387, 0.35091271, 0.76169186, 0.57906099, 0.98890751,\n", - " 0.96141125, 0.25731111, 0.67022349, 0.30738175, 0.22752395,\n", - " 0.88743371, 0.6975126 , 0.90094769, 0.55723621, 0.17498322,\n", - " 0.23819869, 0.3564374 , 0.80282856, 0.30243351, 0.80448796,\n", - " 0.48466329, 0.98000332, 0.02199852, 0.18488749, 0.54550893,\n", - " 0.86812643, 0.83792429, 0.89461096, 0.88250996, 0.42808942,\n", - " 0.59296736, 0.79860916, 0.30380101, 0.43271408, 0.15841563,\n", - " 0.56869869, 0.04184787, 0.10550598, 0.60942529, 0.4265301 ,\n", - " 0.57083876, 0.82435567, 0.59211889, 0.96031419, 0.67952074,\n", - " 0.37334926, 0.3645627 , 0.00962004, 0.46270116, 0.24393275,\n", - " 0.61877639, 0.72515794, 0.74112891, 0.78423151, 0.38865816,\n", - " 0.52355693, 0.98749161, 0.0240849 , 0.55514309, 0.01958487,\n", - " 0.849384 , 0.59643945, 0.72927759, 0.50640776, 0.47260815,\n", - " 0.02341713, 0.18155492, 0.92489797, 0.25403256, 0.10852141,\n", - " 0.64066968, 0.77210979, 0.11233653, 0.67487216, 0.66589406,\n", - " 0.69246635, 0.81106247, 0.04426596, 0.72241094, 0.61934481,\n", - " 0.67953836, 0.33271667, 0.70431201, 0.49538386, 0.70481405,\n", - " 0.51488965, 0.35365375, 0.96189495, 0.08626799, 0.65469915,\n", - " 0.75678647, 0.13191874, 0.68800181, 0.3976978 , 0.75082862,\n", - " 0.9238525 , 0.19926841, 0.52864871, 0.84631558, 0.08041432,\n", - " 0.61617623, 0.47972956, 0.41253579, 0.89873016, 0.49668532,\n", - " 0.28110437, 0.71319872, 0.38127862, 0.2969393 , 0.6869966 ,\n", - " 0.93906833, 0.05512929, 0.46130136, 0.31505291, 0.57178749,\n", - " 0.77410248, 0.43127678, 0.46184098, 0.30312938, 0.93041753,\n", - " 0.51114825, 0.79740875, 0.76236662, 0.46370778, 0.98322976,\n", - " 0.03513679, 0.3587125 , 0.13594183, 0.59490432, 0.77843549,\n", - " 0.69222248, 0.89102323, 0.69021418, 0.81951953, 0.13221865,\n", - " 0.86460461, 0.83135051, 0.15770558, 0.18465204, 0.17177554,\n", - " 0.61530353, 0.64739044, 0.40496839, 0.49301272, 0.86611209,\n", - " 0.86025078])" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.spectrum.get()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also directly consume the parameter in a measurement" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 952\n" - ] - } - ], - "source": [ - "meas = Measurement()\n", - "meas.register_parameter(a.spectrum) # register the first independent parameter\n", - "\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((a.spectrum, a.spectrum.get(),))\n", - " \n", - " dataid = datasaver.run_id # convenient to have for plotting" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.dataset.plotting import plot_by_id" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And plot it" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.6" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": false - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/examples/DataSet/Simple Example of new ParameterWithSetpoints.ipynb b/docs/examples/DataSet/Simple Example of new ParameterWithSetpoints.ipynb new file mode 100644 index 00000000000..ed29993a991 --- /dev/null +++ b/docs/examples/DataSet/Simple Example of new ParameterWithSetpoints.ipynb @@ -0,0 +1,536 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple Example of ParameterWithSetpoints\n", + "This notebook has an example of a new simpler ArrayParameter replacement\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument.parameter import Parameter, _BaseParameter" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Optional, Union, Iterable, Callable\n", + "Number = Union[float, int]\n", + "from qcodes.utils.validators import Validator" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.utils.validators import Numbers\n", + "from qcodes.instrument.base import Instrument\n", + "from qcodes.dataset.measurements import Measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.dataset.database import initialise_database\n", + "from qcodes.dataset.experiment_container import new_experiment" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument.parameter import ParameterWithSetpoints, GeneratedSetPoints" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we define an dummy instrument that returns something like a frequency spectrum from `f_start` to `f_stop`\n", + "in `n_points` steps. The functionality of the ArrayParameter is implemented only by having a reference to it's setpoints which is consumed by the dataset context manager. To do this we only have to define the parameter for the setpoints and the spectrum and let the parameter know that the frequency axis is the setpoints " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "class DummyArray(ParameterWithSetpoints):\n", + " \n", + " def get_raw(self):\n", + " npoints = self.root_instrument.n_points()\n", + " return np.random.rand(npoints)\n", + " \n", + "\n", + "class DummySpectrumAnalyzer(Instrument):\n", + " \n", + " def __init__(self, name, **kwargs):\n", + " \n", + " super().__init__(name, **kwargs)\n", + " \n", + "\n", + " self.add_parameter('f_start',\n", + " initial_value=0,\n", + " unit='Hz',\n", + " label='f start',\n", + " vals=Numbers(0,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + "\n", + " self.add_parameter('f_stop',\n", + " unit='Hz',\n", + " label='f stop',\n", + " vals=Numbers(1,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + "\n", + " self.add_parameter('n_points',\n", + " unit='',\n", + " vals=Numbers(1,1e3),\n", + " get_cmd=None,\n", + " set_cmd=None)\n", + " \n", + " self.add_parameter('freq_axis',\n", + " unit='Hz',\n", + " label='Freq Axis',\n", + " parameter_class=GeneratedSetPoints,\n", + " startparam=self.f_start,\n", + " stopparam=self.f_stop,\n", + " numpointsparam=self.n_points)\n", + " \n", + " self.add_parameter('spectrum',\n", + " unit='dBm',\n", + " setpoints=(self.freq_axis,),\n", + " label='Spectrum',\n", + " parameter_class=DummyArray)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tutorial_exp#no sample#142@c:\\Users\\jenielse\\mymainfolder\\experiments.db\n", + "------------------------------------------------------------------------" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "initialise_database()\n", + "new_experiment(name='tutorial_exp', sample_name=\"no sample\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "a = DummySpectrumAnalyzer('foobar')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we setup the limits of the spectrum" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "a.f_start(0)\n", + "a.f_stop(500)\n", + "a.n_points(501)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can grab the axis" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.,\n", + " 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21.,\n", + " 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32.,\n", + " 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43.,\n", + " 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,\n", + " 55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65.,\n", + " 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76.,\n", + " 77., 78., 79., 80., 81., 82., 83., 84., 85., 86., 87.,\n", + " 88., 89., 90., 91., 92., 93., 94., 95., 96., 97., 98.,\n", + " 99., 100., 101., 102., 103., 104., 105., 106., 107., 108., 109.,\n", + " 110., 111., 112., 113., 114., 115., 116., 117., 118., 119., 120.,\n", + " 121., 122., 123., 124., 125., 126., 127., 128., 129., 130., 131.,\n", + " 132., 133., 134., 135., 136., 137., 138., 139., 140., 141., 142.,\n", + " 143., 144., 145., 146., 147., 148., 149., 150., 151., 152., 153.,\n", + " 154., 155., 156., 157., 158., 159., 160., 161., 162., 163., 164.,\n", + " 165., 166., 167., 168., 169., 170., 171., 172., 173., 174., 175.,\n", + " 176., 177., 178., 179., 180., 181., 182., 183., 184., 185., 186.,\n", + " 187., 188., 189., 190., 191., 192., 193., 194., 195., 196., 197.,\n", + " 198., 199., 200., 201., 202., 203., 204., 205., 206., 207., 208.,\n", + " 209., 210., 211., 212., 213., 214., 215., 216., 217., 218., 219.,\n", + " 220., 221., 222., 223., 224., 225., 226., 227., 228., 229., 230.,\n", + " 231., 232., 233., 234., 235., 236., 237., 238., 239., 240., 241.,\n", + " 242., 243., 244., 245., 246., 247., 248., 249., 250., 251., 252.,\n", + " 253., 254., 255., 256., 257., 258., 259., 260., 261., 262., 263.,\n", + " 264., 265., 266., 267., 268., 269., 270., 271., 272., 273., 274.,\n", + " 275., 276., 277., 278., 279., 280., 281., 282., 283., 284., 285.,\n", + " 286., 287., 288., 289., 290., 291., 292., 293., 294., 295., 296.,\n", + " 297., 298., 299., 300., 301., 302., 303., 304., 305., 306., 307.,\n", + " 308., 309., 310., 311., 312., 313., 314., 315., 316., 317., 318.,\n", + " 319., 320., 321., 322., 323., 324., 325., 326., 327., 328., 329.,\n", + " 330., 331., 332., 333., 334., 335., 336., 337., 338., 339., 340.,\n", + " 341., 342., 343., 344., 345., 346., 347., 348., 349., 350., 351.,\n", + " 352., 353., 354., 355., 356., 357., 358., 359., 360., 361., 362.,\n", + " 363., 364., 365., 366., 367., 368., 369., 370., 371., 372., 373.,\n", + " 374., 375., 376., 377., 378., 379., 380., 381., 382., 383., 384.,\n", + " 385., 386., 387., 388., 389., 390., 391., 392., 393., 394., 395.,\n", + " 396., 397., 398., 399., 400., 401., 402., 403., 404., 405., 406.,\n", + " 407., 408., 409., 410., 411., 412., 413., 414., 415., 416., 417.,\n", + " 418., 419., 420., 421., 422., 423., 424., 425., 426., 427., 428.,\n", + " 429., 430., 431., 432., 433., 434., 435., 436., 437., 438., 439.,\n", + " 440., 441., 442., 443., 444., 445., 446., 447., 448., 449., 450.,\n", + " 451., 452., 453., 454., 455., 456., 457., 458., 459., 460., 461.,\n", + " 462., 463., 464., 465., 466., 467., 468., 469., 470., 471., 472.,\n", + " 473., 474., 475., 476., 477., 478., 479., 480., 481., 482., 483.,\n", + " 484., 485., 486., 487., 488., 489., 490., 491., 492., 493., 494.,\n", + " 495., 496., 497., 498., 499., 500.])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.freq_axis()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or the spectrum" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0.72571352, 0.90632183, 0.33183049, 0.02012441, 0.47057386,\n", + " 0.90672402, 0.07999109, 0.61693661, 0.30530647, 0.10985965,\n", + " 0.60918186, 0.34274291, 0.43832254, 0.76568971, 0.21721021,\n", + " 0.30198089, 0.47201838, 0.97928559, 0.7715346 , 0.23269826,\n", + " 0.36167025, 0.80635443, 0.04952206, 0.58616747, 0.40224088,\n", + " 0.45277086, 0.02814571, 0.07327414, 0.63791345, 0.18959364,\n", + " 0.65795672, 0.67999541, 0.05855894, 0.02249179, 0.40130862,\n", + " 0.54845244, 0.2443827 , 0.73592797, 0.9013913 , 0.59558038,\n", + " 0.24921754, 0.00510943, 0.85173873, 0.99469415, 0.3457128 ,\n", + " 0.61190606, 0.86541492, 0.03245227, 0.75744 , 0.01621978,\n", + " 0.86318191, 0.99017436, 0.60923479, 0.67913571, 0.4967267 ,\n", + " 0.03686535, 0.36743032, 0.53714849, 0.72401575, 0.94879797,\n", + " 0.84441913, 0.89020992, 0.21399512, 0.88068879, 0.36922398,\n", + " 0.95177315, 0.39291993, 0.06345901, 0.12453757, 0.59359891,\n", + " 0.47722406, 0.11144605, 0.26755104, 0.76426021, 0.46995979,\n", + " 0.6373366 , 0.38905457, 0.28229169, 0.75277916, 0.86484352,\n", + " 0.95307285, 0.61320484, 0.18912997, 0.5053552 , 0.95201004,\n", + " 0.29930822, 0.96947378, 0.37089328, 0.29869885, 0.67549094,\n", + " 0.59300973, 0.73171001, 0.79902709, 0.59934004, 0.70940563,\n", + " 0.56030827, 0.75177476, 0.72089084, 0.9550844 , 0.57847848,\n", + " 0.60957107, 0.1517757 , 0.38754644, 0.09730288, 0.59988402,\n", + " 0.26167866, 0.00287584, 0.76134196, 0.72431838, 0.72975611,\n", + " 0.22905784, 0.18651577, 0.48891715, 0.57899863, 0.4710521 ,\n", + " 0.10136816, 0.69808045, 0.02561995, 0.08323249, 0.77192287,\n", + " 0.38029957, 0.9954691 , 0.64841041, 0.90485035, 0.45524682,\n", + " 0.89615322, 0.1358363 , 0.48303273, 0.2959501 , 0.13139568,\n", + " 0.8123182 , 0.7683797 , 0.67372457, 0.96291618, 0.84549104,\n", + " 0.95942812, 0.27444138, 0.23508412, 0.26097708, 0.40263297,\n", + " 0.28233152, 0.54483201, 0.91830492, 0.1457073 , 0.40617229,\n", + " 0.35904864, 0.02131232, 0.57335326, 0.31579837, 0.23954332,\n", + " 0.83839741, 0.28382389, 0.52414372, 0.85262061, 0.06880117,\n", + " 0.40455194, 0.90178558, 0.22408739, 0.7744848 , 0.02481246,\n", + " 0.80764393, 0.26593597, 0.02677597, 0.40965144, 0.8421576 ,\n", + " 0.53731458, 0.89145735, 0.38181248, 0.38428735, 0.80712207,\n", + " 0.09220307, 0.74547953, 0.52355824, 0.14421889, 0.09984613,\n", + " 0.86976546, 0.86983597, 0.75526311, 0.35561927, 0.95147586,\n", + " 0.46415392, 0.91923755, 0.48889277, 0.22755345, 0.26840527,\n", + " 0.62062403, 0.80705705, 0.71891185, 0.69817039, 0.88091927,\n", + " 0.72549422, 0.69001979, 0.10264036, 0.88963743, 0.05742265,\n", + " 0.25475254, 0.63174133, 0.85631804, 0.46140504, 0.89153781,\n", + " 0.09246152, 0.4553433 , 0.82194924, 0.10917984, 0.73418867,\n", + " 0.19001657, 0.45568429, 0.54007574, 0.58392099, 0.30775546,\n", + " 0.4394131 , 0.91735479, 0.50491593, 0.19709832, 0.04327409,\n", + " 0.12994578, 0.60389174, 0.60880184, 0.86196128, 0.461006 ,\n", + " 0.93866109, 0.07467717, 0.96665901, 0.07662807, 0.00650676,\n", + " 0.05117541, 0.5180313 , 0.8942333 , 0.31172786, 0.03383395,\n", + " 0.16083572, 0.98726038, 0.23029171, 0.03815381, 0.27830724,\n", + " 0.78089892, 0.26262639, 0.34292734, 0.74449311, 0.79762933,\n", + " 0.43790091, 0.51195497, 0.28181043, 0.5153651 , 0.30021213,\n", + " 0.33442989, 0.09322682, 0.03990131, 0.99979069, 0.34127417,\n", + " 0.86015426, 0.30417118, 0.9575738 , 0.30270029, 0.50181287,\n", + " 0.11860836, 0.72601674, 0.7365407 , 0.00710955, 0.68799828,\n", + " 0.17416455, 0.53911492, 0.91384936, 0.18843829, 0.63088603,\n", + " 0.29193789, 0.03401586, 0.2651537 , 0.21846207, 0.80779887,\n", + " 0.44912494, 0.00771518, 0.33588898, 0.99925868, 0.32591454,\n", + " 0.64306746, 0.59037939, 0.62749703, 0.82225998, 0.77850614,\n", + " 0.23233915, 0.3631501 , 0.2458376 , 0.87561822, 0.07585749,\n", + " 0.67926546, 0.40504241, 0.91947842, 0.78828305, 0.7828465 ,\n", + " 0.00427593, 0.00283294, 0.43546984, 0.90332049, 0.15497613,\n", + " 0.45345279, 0.64433748, 0.12109508, 0.75966004, 0.23897154,\n", + " 0.21001474, 0.11993474, 0.31404692, 0.68167124, 0.09595568,\n", + " 0.15755628, 0.51734827, 0.07594637, 0.55267866, 0.44948865,\n", + " 0.25025314, 0.38526441, 0.65159328, 0.62017123, 0.25803987,\n", + " 0.4264115 , 0.14115278, 0.26872908, 0.4629822 , 0.08718998,\n", + " 0.57810156, 0.99622881, 0.95761661, 0.89062367, 0.79028311,\n", + " 0.88585828, 0.89394358, 0.04451967, 0.52583018, 0.27224092,\n", + " 0.14832532, 0.7204601 , 0.88138712, 0.16166671, 0.84870318,\n", + " 0.04202383, 0.12059793, 0.16675446, 0.85509329, 0.24051516,\n", + " 0.31051694, 0.65789458, 0.84415465, 0.95522144, 0.55012256,\n", + " 0.06439362, 0.0471405 , 0.4298978 , 0.97980461, 0.30204309,\n", + " 0.1332781 , 0.57028329, 0.71668634, 0.65833129, 0.61765729,\n", + " 0.59033497, 0.67498614, 0.86193156, 0.0719664 , 0.75907468,\n", + " 0.47468334, 0.75966527, 0.09815679, 0.37776018, 0.8208667 ,\n", + " 0.51770517, 0.69423553, 0.56905415, 0.73752259, 0.5912302 ,\n", + " 0.543815 , 0.27079868, 0.13084457, 0.63898715, 0.98408504,\n", + " 0.23782107, 0.29082979, 0.78321311, 0.04698455, 0.43149004,\n", + " 0.29898713, 0.31190781, 0.96342633, 0.85667897, 0.30544318,\n", + " 0.09077967, 0.82440842, 0.10259322, 0.41499891, 0.22650351,\n", + " 0.41287407, 0.00468798, 0.10084611, 0.83298202, 0.84158234,\n", + " 0.23697744, 0.7171173 , 0.22766355, 0.25294449, 0.69188399,\n", + " 0.28100622, 0.12540229, 0.3447357 , 0.16122461, 0.13464566,\n", + " 0.27402472, 0.45150249, 0.59151639, 0.86097983, 0.80896133,\n", + " 0.46221015, 0.64527635, 0.42510658, 0.67139835, 0.80904429,\n", + " 0.30068385, 0.44338639, 0.53308842, 0.90475476, 0.92110973,\n", + " 0.816617 , 0.42493616, 0.22609153, 0.71772722, 0.2188498 ,\n", + " 0.91914612, 0.19662348, 0.98499926, 0.31563325, 0.97379735,\n", + " 0.6651961 , 0.32430088, 0.63782434, 0.83354675, 0.55140114,\n", + " 0.22303504, 0.04978941, 0.51909567, 0.15775337, 0.22066878,\n", + " 0.8610816 , 0.6267583 , 0.28182854, 0.06605268, 0.18431065,\n", + " 0.77677561, 0.52523021, 0.44120459, 0.41657094, 0.44568815,\n", + " 0.77413594, 0.87491547, 0.06874434, 0.55776904, 0.72884754,\n", + " 0.82478796, 0.98673168, 0.7940176 , 0.5361103 , 0.51926828,\n", + " 0.82189625, 0.20471795, 0.24458432, 0.06947301, 0.00567292,\n", + " 0.81583788, 0.66837088, 0.99109122, 0.89918589, 0.94710167,\n", + " 0.74186421, 0.00774864, 0.53096422, 0.7902904 , 0.79997898,\n", + " 0.50096739, 0.28782579, 0.93802907, 0.318469 , 0.08039758,\n", + " 0.17068301, 0.88139886, 0.65884923, 0.14605981, 0.41048688,\n", + " 0.35022301, 0.8821677 , 0.15931134, 0.40747103, 0.81513538,\n", + " 0.11041708, 0.62856525, 0.9785561 , 0.32482764, 0.0215816 ,\n", + " 0.5345427 , 0.50194307, 0.90729726, 0.43601256, 0.62007211,\n", + " 0.96943269])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.spectrum.get()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also directly consume the parameter in a measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 1075\n" + ] + } + ], + "source": [ + "meas = Measurement()\n", + "meas.register_parameter(a.spectrum) # register the first independent parameter\n", + "\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((a.spectrum, a.spectrum.get(),))\n", + " \n", + " dataid = datasaver.run_id # convenient to have for plotting" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.dataset.plotting import plot_by_id" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And plot it" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From baaa572a7b1f40ccf21222ccdfe6e381c4091019 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 25 Oct 2018 15:02:31 +0200 Subject: [PATCH 116/719] make sure notebook has a dataset to save to: --- ...arameter Example with Dual Setpoints.ipynb | 99 ++++++++++--------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb index 1845a1fdc40..00a20b83626 100644 --- a/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb +++ b/docs/examples/An ArrayParameter Example with Dual Setpoints.ipynb @@ -29,6 +29,16 @@ "execution_count": 2, "metadata": {}, "outputs": [], + "source": [ + "from qcodes.dataset.database import initialise_database\n", + "from qcodes.dataset.experiment_container import new_experiment" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], "source": [ "def timetrace(npts: int, dt: float) -> np.ndarray:\n", " \"\"\"\n", @@ -46,7 +56,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -133,13 +143,35 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "osc = OzzyLowScope('osc')" ] }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tutorial_exp#no sample#1@./exp_container_tutorial.db\n", + "----------------------------------------------------" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "initialise_database()\n", + "new_experiment(name='tutorial_exp', sample_name=\"no sample\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -149,14 +181,14 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 947\n" + "Starting experimental run with id: 1\n" ] } ], @@ -174,12 +206,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -196,14 +228,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 948\n" + "Starting experimental run with id: 2\n" ] } ], @@ -218,12 +250,12 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -247,14 +279,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 949\n" + "Starting experimental run with id: 3\n" ] } ], @@ -272,12 +304,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -303,14 +335,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 950\n" + "Starting experimental run with id: 4\n" ] } ], @@ -331,12 +363,12 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -362,14 +394,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 951\n" + "Starting experimental run with id: 5\n" ] } ], @@ -392,12 +424,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -411,27 +443,6 @@ "source": [ "_ = plot_by_id(dataid)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -450,7 +461,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.6.7" } }, "nbformat": 4, From 8ea1d9f6140be7d21b4b3d72b93f62511d146c85 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 25 Oct 2018 15:02:57 +0200 Subject: [PATCH 117/719] This cannot be executed --- ...le with Signal Hound USB-SA124B new Array Parameter.ipynb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb index 38287c9bb69..6d024cfbd5c 100644 --- a/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Signal Hound USB-SA124B new Array Parameter.ipynb @@ -381,7 +381,10 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.6.7" + }, + "nbsphinx": { + "execute": "never" } }, "nbformat": 4, From 161c7df14abc62d1e532c556c01fde46444bb0f6 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 14:48:16 +0100 Subject: [PATCH 118/719] Add parameter with setpoints to dummy instrument --- qcodes/tests/instrument_mocks.py | 56 ++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/instrument_mocks.py b/qcodes/tests/instrument_mocks.py index c47ea7c5fd8..8bb2b4391a2 100644 --- a/qcodes/tests/instrument_mocks.py +++ b/qcodes/tests/instrument_mocks.py @@ -5,8 +5,9 @@ import numpy as np from qcodes.instrument.base import Instrument -from qcodes.utils.validators import Numbers -from qcodes.instrument.parameter import MultiParameter, Parameter, ArrayParameter +from qcodes.utils.validators import Numbers, Arrays +from qcodes.instrument.parameter import MultiParameter, Parameter, \ + ArrayParameter, ParameterWithSetpoints, GeneratedSetPoints from qcodes.instrument.channel import InstrumentChannel, ChannelList log = logging.getLogger(__name__) @@ -95,7 +96,7 @@ def _get_skew_parabola(self): class DummyInstrument(Instrument): - def __init__(self, name='dummy', gates=['dac1', 'dac2', 'dac3'], **kwargs): + def __init__(self, name='dummy', gates=('dac1', 'dac2', 'dac3'), **kwargs): """ Create a dummy instrument that can be used for testing @@ -149,6 +150,43 @@ def __init__(self, parent, name, channel): self.add_parameter(name='dummy_array_parameter', parameter_class=ArraySetPointParam) + self.add_parameter('dummy_start', + initial_value=0, + unit='some unit', + label='f start', + vals=Numbers(0, 1e3), + get_cmd=None, + set_cmd=None) + + self.add_parameter('dummy_stop', + unit='some unit', + label='f stop', + vals=Numbers(1, 1e3), + get_cmd=None, + set_cmd=None) + + self.add_parameter('dummy_n_points', + unit='', + vals=Numbers(1, 1e3), + get_cmd=None, + set_cmd=None) + + self.add_parameter('dummy_sp_axis', + unit='some unit', + label='Dummy sp axis', + parameter_class=GeneratedSetPoints, + startparam=self.dummy_start, + stopparam=self.dummy_stop, + numpointsparam=self.dummy_n_points, + vals=Arrays(shape=(self.dummy_n_points,))) + + self.add_parameter(name='dummy_parameter_with_setpoints', + label='Dummy Parameter with Setpoints', + unit='some other unit', + setpoints=(self.dummy_sp_axis,), + vals=Arrays(shape=(self.dummy_n_points,)), + parameter_class=DummyParameterWithSetpoints1D) + self.add_function(name='log_my_name', call_cmd=partial(log.debug, f'{name}')) @@ -284,6 +322,7 @@ def get_raw(self): self._save_val(items) return items + class ArraySetPointParam(ArrayParameter): """ Arrayparameter which only purpose it to test that units, setpoints @@ -315,6 +354,17 @@ def get_raw(self): return item +class DummyParameterWithSetpoints1D(ParameterWithSetpoints): + """ + Dummy parameter that returns data with a shape based on the + `n_points` parameter in the instrument. + """ + + def get_raw(self): + npoints = self.instrument.dummy_n_points() + return np.random.rand(npoints) + + def setpoint_generator(*sp_bases): """ Helper function to generate setpoints in the format that ArrayParameter From 7e3616278ace84fa375ae8267c87c6e7176da2db Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 14:50:26 +0100 Subject: [PATCH 119/719] Add tests of saving data from parameter with setpoints --- .../test_measurement_context_manager.py | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_measurement_context_manager.py b/qcodes/tests/dataset/test_measurement_context_manager.py index 461e25df5fd..71c0c4f967b 100644 --- a/qcodes/tests/dataset/test_measurement_context_manager.py +++ b/qcodes/tests/dataset/test_measurement_context_manager.py @@ -640,7 +640,7 @@ def test_datasaver_scalars(experiment, DAC, DMM, set_values, get_values, @settings(max_examples=10, deadline=None) @given(N=hst.integers(min_value=2, max_value=500)) @pytest.mark.usefixtures("empty_temp_db") -def test_datasaver_arrays_lists_tuples(N): +def test_datasaver_arrays_lists_tuples(N: int) -> None: new_experiment('firstexp', sample_name='no sample') meas = Measurement() @@ -976,6 +976,49 @@ def test_datasaver_array_parameters_channel(channel_array_instrument, assert datadict['data'].shape == (N * M,) +@settings(max_examples=5, deadline=None) +@given(n=hst.integers(min_value=5, max_value=500)) +@pytest.mark.usefixtures("experiment") +def test_datasaver_parameter_with_setpoints(channel_array_instrument, + DAC, n): + + chan = channel_array_instrument.A + param = chan.dummy_parameter_with_setpoints + chan.dummy_n_points(n) + chan.dummy_start(0) + chan.dummy_stop(100) + meas = Measurement() + meas.register_parameter(param) + + assert len(meas.parameters) == 2 + dependency_name = 'dummy_channel_inst_ChanA_dummy_sp_axis' + + assert meas.parameters[str(param)].depends_on == dependency_name + assert meas.parameters[str(param)].type == 'numeric' + assert meas.parameters[dependency_name].type == 'numeric' + + # Now for a real measurement + with meas.run() as datasaver: + datasaver.add_result((param, param())) + assert datasaver.points_written == n + + expected_params = ('dummy_channel_inst_ChanA_dummy_sp_axis', + 'dummy_channel_inst_ChanA_dummy_parameter_with_setpoints') + ds = load_by_id(datasaver.run_id) + for param in expected_params: + data = ds.get_data(param) + assert len(data) == n + assert len(data[0]) == 1 + datadicts = get_data_by_id(datasaver.run_id) + # one dependent parameter + assert len(datadicts) == 1 + datadicts = datadicts[0] + assert len(datadicts) == len(meas.parameters) + for datadict in datadicts: + assert datadict['data'].shape == (n,) + + + @settings(max_examples=5, deadline=None) @given(N=hst.integers(min_value=5, max_value=500)) @pytest.mark.usefixtures("experiment") From 80a771223d8e34dddc4e0ec4be6d4cebb606286f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 14:51:38 +0100 Subject: [PATCH 120/719] Reflect that results may be Lists and tuples too --- qcodes/dataset/measurements.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index e0f8db2d557..cb318176eea 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -22,8 +22,10 @@ log = logging.getLogger(__name__) array_like_types = (tuple, list, np.ndarray) +scalar_res_types = Union[str, int, float, np.dtype] res_type = Tuple[Union[_BaseParameter, str], - Union[str, int, float, np.dtype, np.ndarray]] + Union[scalar_res_types, np.ndarray, + Sequence[scalar_res_types]]] setpoints_type = Sequence[Union[str, _BaseParameter]] numeric_types = Union[float, int] From b9527c8b2b76e0e36ae5beb54c60c42493284b39 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 14:52:27 +0100 Subject: [PATCH 121/719] Remove redundant type --- qcodes/tests/test_parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/test_parameter.py b/qcodes/tests/test_parameter.py index f7deac8c177..18167594297 100644 --- a/qcodes/tests/test_parameter.py +++ b/qcodes/tests/test_parameter.py @@ -48,7 +48,7 @@ def validate(self, value, context=''): None, # no instrument at all namedtuple('noname', '')(), # no .name namedtuple('blank', 'name')('') # blank .name -) # type: Tuple +) named_instrument = namedtuple('yesname', 'name')('astro') From a0a40a4e47256d1ae1e61dc219140b082f59e363 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 14:54:26 +0100 Subject: [PATCH 122/719] Add validator and some cleanup of parameter --- qcodes/instrument/parameter.py | 62 ++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 6df6baef8ca..2113fabe24b 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -72,7 +72,7 @@ warn_units) from qcodes.utils.metadata import Metadatable from qcodes.utils.command import Command -from qcodes.utils.validators import Validator, Ints, Strings, Enum +from qcodes.utils.validators import Validator, Ints, Strings, Enum, Arrays from qcodes.instrument.sweep_values import SweepFixedValues from qcodes.data.data_array import DataArray @@ -112,16 +112,16 @@ class _BaseParameter(Metadatable): Note that ``CombinedParameter`` is not yet a subclass of ``_BaseParameter`` Args: - name (str): the local name of the parameter. Must be a valid + name: the local name of the parameter. Must be a valid identifier, ie no spaces or special characters or starting with a number. If this parameter is part of an Instrument or Station, this should match how it will be referenced from that parent, ie ``instrument.name`` or ``instrument.parameters[name]`` - instrument (Optional[Instrument]): the instrument this parameter + instrument: the instrument this parameter belongs to, if any - snapshot_get (Optional[bool]): False prevents any update to the + snapshot_get: False prevents any update to the parameter during a snapshot, even if the snapshot was called with ``update=True``, for example if it takes too long to update. Default True. @@ -189,11 +189,11 @@ def __init__(self, name: str, instrument: Optional['Instrument'], snapshot_get: bool=True, metadata: Optional[dict]=None, - step: Optional[Union[int, float]]=None, + step: Optional[Number]=None, scale: Optional[Union[Number, Iterable[Number]]]=None, offset: Optional[Union[Number, Iterable[Number]]]=None, - inter_delay: Union[int, float]=0, - post_delay: Union[int, float]=0, + inter_delay: Number=0, + post_delay: Number=0, val_mapping: Optional[dict]=None, get_parser: Optional[Callable]=None, set_parser: Optional[Callable]=None, @@ -950,7 +950,7 @@ def sweep(self, start, stop, step=None, num=None): class ParameterWithSetpoints(Parameter): """ A parameter that has associated setpoints. The setpoints is nothing - more than a list of other paramameters that descripe the values, names + more than a list of other parameters that describe the values, names and units of the setpoint axis for this parameter. In most cases this will probably be a parameter that returns an array. @@ -962,9 +962,10 @@ class ParameterWithSetpoints(Parameter): documentation of :class:`Parameter` for more details. """ def __init__(self, *args, - setpoints: Sequence[Parameter]=None, **kwargs) -> None: + setpoints: Optional[Sequence[_BaseParameter]]=None, + **kwargs) -> None: if setpoints is None: - self._setpoints = () + self._setpoints = [] else: self.setpoints = setpoints super().__init__(*args, **kwargs) @@ -974,12 +975,45 @@ def setpoints(self): return self._setpoints @setpoints.setter - def setpoints(self, setpoints): + def setpoints(self, setpoints: Sequence[_BaseParameter]): for setpointarray in setpoints: - if not isinstance(setpointarray, Parameter): + if not isinstance(setpointarray, _BaseParameter): raise RuntimeError self._setpoints = setpoints + def validate_consistent_shape(self) -> bool: + """ + Verifies that the shape of the Array Validator of the parameter + is consistent with the Validator of the Setpoints. This requires that + both the setpoints and the actual parameters have validators + of type Arrays with a defined shape. + """ + output_shape = self.vals.shape + + if not isinstance(self.vals, Arrays): + raise RuntimeError("Can only validate shapes for Array " + "Parameters") + + setpoints_shape_list = [] + for sp in self.setpoints: + if not isinstance(self.vals, Arrays): + raise RuntimeError("Can only validate shapes for Array " + "Parameters") + setpoints_shape_list.extend(sp.vals.shape) + setpoints_shape = tuple(setpoints_shape_list) + + if output_shape is None: + raise RuntimeError("Trying to verify shape but output " + "does not have any shape") + if None in output_shape or None in setpoints_shape: + raise RuntimeError(f"One or more dimensions have unknown shape" + f"when comparing output: {output_shape} to " + f"setpoints: {setpoints_shape}") + + if output_shape != setpoints_shape: + return False + return True + class GeneratedSetPoints(Parameter): """ @@ -1352,8 +1386,8 @@ def __init__(self, @property def short_names(self): """ - short_names is indentical to names i.e. the names of the paramter parts - but does not add the intrument name. + short_names is identical to names i.e. the names of the parameter + parts but does not add the instrument name. It exists for consistency with instruments and other parameters. """ From 3e82c559656bb723793a8e2cd9728512dd907522 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 15:39:16 +0100 Subject: [PATCH 123/719] Correct some types --- qcodes/instrument/parameter.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 2113fabe24b..4eba0c98dfa 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -965,7 +965,7 @@ def __init__(self, *args, setpoints: Optional[Sequence[_BaseParameter]]=None, **kwargs) -> None: if setpoints is None: - self._setpoints = [] + self._setpoints: Sequence[_BaseParameter] = [] else: self.setpoints = setpoints super().__init__(*args, **kwargs) @@ -988,13 +988,11 @@ def validate_consistent_shape(self) -> bool: both the setpoints and the actual parameters have validators of type Arrays with a defined shape. """ - output_shape = self.vals.shape - if not isinstance(self.vals, Arrays): raise RuntimeError("Can only validate shapes for Array " "Parameters") - - setpoints_shape_list = [] + output_shape = self.vals.shape + setpoints_shape_list: List[int] = [] for sp in self.setpoints: if not isinstance(self.vals, Arrays): raise RuntimeError("Can only validate shapes for Array " From 134d067a1a6ec959dfd1ba64c8aaffb7ea5a0eca Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 6 Nov 2018 15:39:34 +0100 Subject: [PATCH 124/719] Dont type this just yet --- qcodes/tests/dataset/test_measurement_context_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_measurement_context_manager.py b/qcodes/tests/dataset/test_measurement_context_manager.py index 71c0c4f967b..2631ee962a5 100644 --- a/qcodes/tests/dataset/test_measurement_context_manager.py +++ b/qcodes/tests/dataset/test_measurement_context_manager.py @@ -640,7 +640,7 @@ def test_datasaver_scalars(experiment, DAC, DMM, set_values, get_values, @settings(max_examples=10, deadline=None) @given(N=hst.integers(min_value=2, max_value=500)) @pytest.mark.usefixtures("empty_temp_db") -def test_datasaver_arrays_lists_tuples(N: int) -> None: +def test_datasaver_arrays_lists_tuples(N): new_experiment('firstexp', sample_name='no sample') meas = Measurement() From 09af75e051e1b9d1b68e057286fa68240ef20352 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 15 Nov 2018 15:44:27 +0100 Subject: [PATCH 125/719] Typo --- qcodes/instrument/parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 4eba0c98dfa..fa5ee84b2ed 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -994,7 +994,7 @@ def validate_consistent_shape(self) -> bool: output_shape = self.vals.shape setpoints_shape_list: List[int] = [] for sp in self.setpoints: - if not isinstance(self.vals, Arrays): + if not isinstance(sp.vals, Arrays): raise RuntimeError("Can only validate shapes for Array " "Parameters") setpoints_shape_list.extend(sp.vals.shape) From 325f32d84abe51c2125744bc6b4518f4b0caad91 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 15:27:44 +0100 Subject: [PATCH 126/719] Extract making ConnectionPlus into separate function --- qcodes/dataset/sqlite_base.py | 27 +++++++++++++++---- .../tests/dataset/test_sqlite_connection.py | 25 +++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 qcodes/tests/dataset/test_sqlite_connection.py diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 00dc00be102..313593a49d9 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -744,11 +744,7 @@ def atomic(conn: SomeConnection): - conn: connection to guard """ - if not(hasattr(conn, 'atomic_in_progress')): - conn = ConnectionPlus(conn) - conn.atomic_in_progress = False - else: - conn = cast(ConnectionPlus, conn) + conn = make_plus_connection_from(conn) is_outmost = not(conn.atomic_in_progress) conn.atomic_in_progress = True @@ -776,6 +772,27 @@ def atomic(conn: SomeConnection): conn.isolation_level = old_level +def make_plus_connection_from(conn: SomeConnection) -> ConnectionPlus: + """ + Makes a ConnectionPlus connection object out of a given argument. + + If the given connection is already a ConnectionPlus, then it is returned + without any changes. + + Args: + conn: an sqlite connection object as defined by SomeConnection type + + Returns: + the same connection as ConnectionPlus object + """ + if not (hasattr(conn, 'atomic_in_progress')): + conn = ConnectionPlus(conn) + conn.atomic_in_progress = False + else: + conn = cast(ConnectionPlus, conn) + return conn + + def init_db(conn: SomeConnection)->None: with atomic(conn) as conn: transaction(conn, _experiment_table_schema) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py new file mode 100644 index 00000000000..73cd2dec358 --- /dev/null +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -0,0 +1,25 @@ +import sqlite3 + +import pytest + +from qcodes.dataset.sqlite_base import ConnectionPlus, make_plus_connection_from + + +@pytest.mark.parametrize( + argnames='conn', + argvalues=(sqlite3.connect(':memory:'), + ConnectionPlus(sqlite3.connect(':memory:'))), + ids=('sqlite3.Connection', 'ConnectionPlus') +) +def test_make_plus_connection_from(conn): + plus_conn = make_plus_connection_from(conn) + + assert isinstance(plus_conn, ConnectionPlus) + + if isinstance(conn, ConnectionPlus): + # make_plus_connection_from does not change this, hence it should be + # equal to the value from `conn` (which is True, see ConnectionPlus) + assert conn.atomic_in_progress is plus_conn.atomic_in_progress + else: + # make_plus_connection_from explicitly sets this to False + assert False is plus_conn.atomic_in_progress From 07cc37c1767c9365df30cd3a397eb503b3450dbf Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 15:52:23 +0100 Subject: [PATCH 127/719] Add basic test for ConnectionPlus --- qcodes/tests/dataset/test_sqlite_connection.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 73cd2dec358..ffab0eedc92 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -5,6 +5,16 @@ from qcodes.dataset.sqlite_base import ConnectionPlus, make_plus_connection_from +def test_connection_plus(): + sqlite_conn = sqlite3.connect(':memory:') + plus_conn = ConnectionPlus(sqlite_conn) + + assert isinstance(plus_conn, ConnectionPlus) + assert isinstance(plus_conn, sqlite3.Connection) + # reason for the value of "True" here is unknown + assert True is plus_conn.atomic_in_progress + + @pytest.mark.parametrize( argnames='conn', argvalues=(sqlite3.connect(':memory:'), From 98bf334ba548767514436c12c33271633956c593 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 17:03:38 +0100 Subject: [PATCH 128/719] Capture behavior of atomic context manager and ConnectionPlus This behavior is quite questionable, hence comments in test code --- .../tests/dataset/test_sqlite_connection.py | 142 +++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index ffab0eedc92..e8e1e04fa21 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -2,7 +2,39 @@ import pytest -from qcodes.dataset.sqlite_base import ConnectionPlus, make_plus_connection_from +from qcodes.dataset.sqlite_base import ConnectionPlus, \ + make_plus_connection_from, atomic + + +def sqlite_conn_in_transaction(conn: sqlite3.Connection): + assert isinstance(conn, sqlite3.Connection) + assert True is conn.in_transaction + assert None is conn.isolation_level + return True + + +def plus_conn_in_transaction(conn: ConnectionPlus): + assert isinstance(conn, ConnectionPlus) + assert True is conn.atomic_in_progress + assert None is conn.isolation_level + assert True is conn.in_transaction + return True + + +def sqlite_conn_is_idle(conn: sqlite3.Connection, isolation=None): + assert isinstance(conn, sqlite3.Connection) + assert False is conn.in_transaction + assert isolation == conn.isolation_level + return True + + +def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): + assert isinstance(conn, ConnectionPlus) + # assert False is conn.atomic_in_progress <-- should it be? + assert True is conn.atomic_in_progress + assert isolation == conn.isolation_level + assert False is conn.in_transaction + return True def test_connection_plus(): @@ -13,6 +45,7 @@ def test_connection_plus(): assert isinstance(plus_conn, sqlite3.Connection) # reason for the value of "True" here is unknown assert True is plus_conn.atomic_in_progress + # assert False is plus_conn.atomic_in_progress <-- should it be? @pytest.mark.parametrize( @@ -33,3 +66,110 @@ def test_make_plus_connection_from(conn): else: # make_plus_connection_from explicitly sets this to False assert False is plus_conn.atomic_in_progress + + +def test_atomic_on_outmost_sqlite_connection(): + sqlite_conn = sqlite3.connect(':memory:') + isolation_level = sqlite_conn.isolation_level + assert False is sqlite_conn.in_transaction + + with atomic(sqlite_conn) as atomic_conn: + assert sqlite_conn_in_transaction(sqlite_conn) + assert plus_conn_in_transaction(atomic_conn) + + assert sqlite_conn_is_idle(sqlite_conn, isolation_level) + assert plus_conn_is_idle(atomic_conn, isolation_level) + + +def test_atomic_on_outmost_plus_connection(): + sqlite_conn = sqlite3.connect(':memory:') + plus_conn = ConnectionPlus(sqlite_conn) + + atomic_in_progress = plus_conn.atomic_in_progress + + isolation_level = plus_conn.isolation_level + assert False is plus_conn.in_transaction + + with atomic(plus_conn) as atomic_conn: + assert isinstance(atomic_conn, ConnectionPlus) + + assert True is atomic_conn.atomic_in_progress + + # assert None is atomic_conn.isolation_level <-- should it be? + assert isolation_level == atomic_conn.isolation_level + # assert None is plus_conn.isolation_level <-- should it be? + assert isolation_level == plus_conn.isolation_level + + # assert True is plus_conn.in_transaction <-- should it be? + assert False is plus_conn.in_transaction + # assert True is atomic_conn.in_transaction <-- should it be? + assert False is atomic_conn.in_transaction + + assert isolation_level == plus_conn.isolation_level + assert False is plus_conn.in_transaction + + assert False is atomic_conn.in_transaction + + assert atomic_in_progress is atomic_conn.atomic_in_progress + + +def test_two_atomics_on_outmost_sqlite_connection(): + sqlite_conn = sqlite3.connect(':memory:') + + isolation_level = sqlite_conn.isolation_level + assert False is sqlite_conn.in_transaction + + with atomic(sqlite_conn) as atomic_conn_1: + assert sqlite_conn_in_transaction(sqlite_conn) + assert plus_conn_in_transaction(atomic_conn_1) + + with atomic(atomic_conn_1) as atomic_conn_2: + assert sqlite_conn_in_transaction(sqlite_conn) + assert plus_conn_in_transaction(atomic_conn_2) + assert plus_conn_in_transaction(atomic_conn_1) + + assert sqlite_conn_in_transaction(sqlite_conn) + assert plus_conn_in_transaction(atomic_conn_1) + assert plus_conn_in_transaction(atomic_conn_2) + + assert sqlite_conn_is_idle(sqlite_conn, isolation_level) + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + assert plus_conn_is_idle(atomic_conn_2, isolation_level) + + +def test_two_atomics_on_outmost_plus_connection(): + sqlite_conn = sqlite3.connect(':memory:') + plus_conn = ConnectionPlus(sqlite_conn) + atomic_in_progress = plus_conn.atomic_in_progress + + isolation_level = plus_conn.isolation_level + assert False is plus_conn.in_transaction + + with atomic(plus_conn) as atomic_conn_1: + # assert plus_conn_in_transaction(plus_conn) + assert plus_conn_is_idle(plus_conn, isolation_level) + # assert plus_conn_in_transaction(atomic_conn_1) + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + + with atomic(atomic_conn_1) as atomic_conn_2: + # assert plus_conn_in_transaction(plus_conn) <-- should it be? + assert plus_conn_is_idle(plus_conn, isolation_level) + # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + # assert plus_conn_in_transaction(atomic_conn_2) <-- should it be? + assert plus_conn_is_idle(atomic_conn_2, isolation_level) + + # assert plus_conn_in_transaction(plus_conn) <-- should it be? + assert plus_conn_is_idle(plus_conn, isolation_level) + # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + # assert plus_conn_in_transaction(atomic_conn_2) <-- should it be? + assert plus_conn_is_idle(atomic_conn_2, isolation_level) + + assert plus_conn_is_idle(plus_conn, isolation_level) + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + assert plus_conn_is_idle(atomic_conn_2, isolation_level) + + assert atomic_in_progress == plus_conn.atomic_in_progress + assert atomic_in_progress == atomic_conn_1.atomic_in_progress + assert atomic_in_progress == atomic_conn_2.atomic_in_progress From de15768550a55aeeb1cfa180bcdc9c9d6d5c6e5d Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 20:33:50 +0100 Subject: [PATCH 129/719] Fix DataSet.unsubscribe bug by adding trigger_id to _Subscriber DataSet.unsubscribe used to unsubscribe by _Subscriber._id but this raises an exception because unsubscribing involved removing a corresponding trigger from the database, and the id of the trigger is not equal to the id of the _Subscriber itself: the trigger id has a prefix 'sub'. --- qcodes/dataset/data_set.py | 5 +++-- qcodes/tests/dataset/test_subscribing.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 7f93402a935..2d023a71cce 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -109,6 +109,7 @@ def __init__(self, self.callback = functools.partial(callback, **callback_kwargs) self.callback_id = f"callback{self._id}" + self.trigger_id = f"sub{self._id}" conn = dataSet.conn @@ -117,7 +118,7 @@ def __init__(self, parameters = dataSet.get_parameters() sql_param_list = ",".join([f"NEW.{p.name}" for p in parameters]) sql_create_trigger_for_callback = f""" - CREATE TRIGGER sub{self._id} + CREATE TRIGGER {self.trigger_id} AFTER INSERT ON '{self.table_name}' BEGIN SELECT {self.callback_id}({sql_param_list}); @@ -805,8 +806,8 @@ def unsubscribe(self, uuid: str) -> None: Remove subscriber with the provided uuid """ with atomic(self.conn) as self.conn: - self._remove_trigger(uuid) sub = self.subscribers[uuid] + self._remove_trigger(sub.trigger_id) sub.schedule_stop() sub.join() del self.subscribers[uuid] diff --git a/qcodes/tests/dataset/test_subscribing.py b/qcodes/tests/dataset/test_subscribing.py index d5aefe1d91b..42c8d478e93 100644 --- a/qcodes/tests/dataset/test_subscribing.py +++ b/qcodes/tests/dataset/test_subscribing.py @@ -9,6 +9,7 @@ import qcodes from qcodes.dataset.param_spec import ParamSpec # pylint: disable=unused-import +from qcodes.dataset.sqlite_base import atomic_transaction from qcodes.tests.dataset.temporary_databases import ( empty_temp_db, experiment, dataset) # pylint: enable=unused-import @@ -85,6 +86,17 @@ def test_basic_subscription(dataset, basic_subscriber): expected_state[x+1] = [(x, y)] assert dataset.subscribers[sub_id].state == expected_state + dataset.unsubscribe(sub_id) + + assert len(dataset.subscribers) == 0 + assert list(dataset.subscribers.keys()) == [] + + # Ensure the trigger for the subscriber have been removed from the database + get_triggers_sql = "SELECT * FROM sqlite_master WHERE TYPE = 'trigger';" + triggers = atomic_transaction( + dataset.conn, get_triggers_sql).fetchall() + assert len(triggers) == 0 + def test_subscription_from_config(dataset, basic_subscriber): """ From b435c75b9ccfaca4fca8d185f15738ca98d1988a Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 21:09:08 +0100 Subject: [PATCH 130/719] Deprecate DataSet.modify_results (w/ 's') + test; does not always work Also add an xfail test that covers working functionality and non-working --- qcodes/dataset/data_set.py | 3 +++ qcodes/tests/dataset/test_dataset_basic.py | 28 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 2d023a71cce..490cb3c6bd1 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -606,6 +606,9 @@ def modify_result(self, index: int, results: Dict[str, VALUES]) -> None: list(results.values()) ) + @deprecate(reason='it is an experimental functionality, and it is not ' + 'known whether it will remain or it will be removed.', + alternative='modify_result') def modify_results(self, start_index: int, updates: List[Dict[str, VALUES]]): """ diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index e0dbcfd830b..1676d28bb37 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -291,6 +291,34 @@ def test_adding_too_many_results(): dataset.add_results(results) +def test_modify_results(dataset): + xparam = ParamSpec("x", "numeric") + dataset.add_parameter(xparam) + dataset.add_result({'x': 0}) + dataset.add_result({'x': 1}) + + pytest.deprecated_call(dataset.modify_results, 0, [{'x': [10]}]) + assert [[10], [1]] == dataset.get_data(xparam) + + pytest.deprecated_call(dataset.modify_results, 1, [{'x': [14]}]) + assert [[10], [14]] == dataset.get_data(xparam) + + with pytest.raises(RuntimeError, + match='Rolling back due to unhandled exception'): + # not sure calling `modify_results` like this is correct, anyway it + # is difficult to find out what the call signature for multiple + # results is supposed to look like... + pytest.deprecated_call( + dataset.modify_results, 0, [{'x': [5]}, {'x': [6]}]) + assert [[5], [6]] == dataset.get_data(xparam) + + pytest.xfail('modify_results does not seem to work for cases where ' + 'multiple values of multiple parameters need to be changed. ' + 'Anyway, the signature needs to be revisited, ' + 'and consequently the correct behavior needs to be ' + 'implemented and covered with tests.') + + @pytest.mark.usefixtures("experiment") def test_modify_result(): dataset = new_data_set("test_modify_result") From 815a457a7b3bcc1f353a4a33b459810dbbf7d5cd Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 19 Nov 2018 21:11:24 +0100 Subject: [PATCH 131/719] Add failing tests for some DataSet methods which do not commit to db This is due to both: bug in `atomic` context manager, and the fact that in those methods DataSet's connection object gets reassigned to a modified one that `atomic` returns. These bugs will be fixed in further commits. --- qcodes/tests/dataset/test_dataset_basic.py | 138 ++++++++++++++++----- qcodes/tests/dataset/test_subscribing.py | 46 +++++++ 2 files changed, 151 insertions(+), 33 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 1676d28bb37..069378f3d63 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1,4 +1,5 @@ import itertools +import re import pytest import numpy as np @@ -10,6 +11,8 @@ from qcodes import load_by_id, load_by_counter from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies +from qcodes.tests.dataset.test_database_creation_and_upgrading import \ + error_caused_by from qcodes.tests.dataset.test_descriptions import some_paramspecs from qcodes.dataset.sqlite_base import _unicode_categories from qcodes.dataset.database import get_DB_location @@ -22,6 +25,19 @@ n_experiments = 0 +def make_shadow_dataset(dataset: DataSet): + """ + Creates a new DataSet object that points to the same run_id in the same + database file as the given dataset object. + + Note that in order to achieve it `path_to_db` because this will create a + new sqlite3 connection object behind the scenes. This is very useful for + situations where one needs to assert the underlying modifications to the + database file. + """ + return DataSet(path_to_db=dataset.path_to_db, run_id=dataset.run_id) + + @pytest.mark.usefixtures("experiment") def test_has_attributes_after_init(): """ @@ -161,7 +177,10 @@ def test_add_paramspec(dataset): # Now retrieve the paramspecs - paramspecs = dataset.paramspecs + shadow_ds = make_shadow_dataset(dataset) + + paramspecs = shadow_ds.paramspecs + expected_keys = ['a_param', 'b_param', 'c_param'] keys = sorted(list(paramspecs.keys())) assert keys == expected_keys @@ -171,6 +190,8 @@ def test_add_paramspec(dataset): assert paramspecs['c_param'].inferred_from == 'a_param, b_param' + assert paramspecs == dataset.paramspecs + def test_add_paramspec_one_by_one(dataset): exps = experiments() @@ -185,7 +206,11 @@ def test_add_paramspec_one_by_one(dataset): ParamSpec("c", "array")] for parameter in parameters: dataset.add_parameter(parameter) - paramspecs = dataset.paramspecs + + shadow_ds = make_shadow_dataset(dataset) + + paramspecs = shadow_ds.paramspecs + expected_keys = ['a', 'b', 'c'] keys = sorted(list(paramspecs.keys())) assert keys == expected_keys @@ -193,12 +218,15 @@ def test_add_paramspec_one_by_one(dataset): ps = paramspecs[expected_param_name] assert ps.name == expected_param_name + assert paramspecs == dataset.paramspecs + # Test that is not possible to add the same parameter again to the dataset with pytest.raises(ValueError, match=f'Duplicate parameter name: ' f'{parameters[0].name}'): dataset.add_parameter(parameters[0]) assert len(dataset.paramspecs.keys()) == 3 + assert len(shadow_ds.paramspecs.keys()) == 3 @pytest.mark.usefixtures("experiment") @@ -222,8 +250,13 @@ def test_add_data_1d(): y = 3 * x + 10 expected_y.append([y]) mydataset.add_result({"x": x, "y": y}) + + shadow_ds = make_shadow_dataset(mydataset) + assert mydataset.get_data('x') == expected_x assert mydataset.get_data('y') == expected_y + assert shadow_ds.get_data('x') == expected_x + assert shadow_ds.get_data('y') == expected_y with pytest.raises(ValueError): mydataset.add_result({'y': 500}) @@ -258,9 +291,16 @@ def test_add_data_array(): y = np.random.random_sample(10) expected_y.append([y]) mydataset.add_result({"x": x, "y": y}) + + shadow_ds = make_shadow_dataset(mydataset) + assert mydataset.get_data('x') == expected_x + assert shadow_ds.get_data('x') == expected_x + y_data = mydataset.get_data('y') np.testing.assert_allclose(y_data, expected_y) + y_data = shadow_ds.get_data('y') + np.testing.assert_allclose(y_data, expected_y) @pytest.mark.usefixtures("experiment") @@ -338,54 +378,86 @@ def test_modify_result(): dataset.add_result({'x': 0, 'y': 1, 'z': zdata}) - assert dataset.get_data('x')[0][0] == xdata - assert dataset.get_data('y')[0][0] == ydata - assert (dataset.get_data('z')[0][0] == zdata).all() + shadow_ds = make_shadow_dataset(dataset) - with pytest.raises(ValueError): - dataset.modify_result(0, {' x': 1}) + try: + assert dataset.get_data('x')[0][0] == xdata + assert dataset.get_data('y')[0][0] == ydata + assert (dataset.get_data('z')[0][0] == zdata).all() - xdata = 1 - ydata = 12 - zdata = np.linspace(0, 1, 99) + assert shadow_ds.get_data('x')[0][0] == xdata + assert shadow_ds.get_data('y')[0][0] == ydata + assert (shadow_ds.get_data('z')[0][0] == zdata).all() - dataset.modify_result(0, {'x': xdata}) - assert dataset.get_data('x')[0][0] == xdata + with pytest.raises(ValueError): + dataset.modify_result(0, {' x': 1}) - dataset.modify_result(0, {'y': ydata}) - assert dataset.get_data('y')[0][0] == ydata + xdata = 1 + ydata = 12 + zdata = np.linspace(0, 1, 99) - dataset.modify_result(0, {'z': zdata}) - assert (dataset.get_data('z')[0][0] == zdata).all() + dataset.modify_result(0, {'x': xdata}) + assert dataset.get_data('x')[0][0] == xdata + assert shadow_ds.get_data('x')[0][0] == xdata - dataset.mark_complete() + dataset.modify_result(0, {'y': ydata}) + assert dataset.get_data('y')[0][0] == ydata + assert shadow_ds.get_data('y')[0][0] == ydata - with pytest.raises(CompletedError): - dataset.modify_result(0, {'x': 2}) + dataset.modify_result(0, {'z': zdata}) + assert (dataset.get_data('z')[0][0] == zdata).all() + assert (shadow_ds.get_data('z')[0][0] == zdata).all() + dataset.mark_complete() -@settings(max_examples=25, deadline=None) -@given(N=hst.integers(min_value=1, max_value=10000), - M=hst.integers(min_value=1, max_value=10000)) -@pytest.mark.usefixtures("experiment") -def test_add_parameter_values(N, M): + with pytest.raises(CompletedError): + dataset.modify_result(0, {'x': 2}) + + finally: + shadow_ds.conn.close() - mydataset = new_data_set("test_add_parameter_values") + +# @settings(max_examples=25, deadline=None) +# @given(N=hst.integers(min_value=1, max_value=10000), +# M=hst.integers(min_value=1, max_value=10000)) +# def test_add_parameter_values(dataset, N, M): +def test_add_parameter_values(dataset, N=2, M=3): xparam = ParamSpec('x', 'numeric') - mydataset.add_parameter(xparam) + dataset.add_parameter(xparam) x_results = [{'x': x} for x in range(N)] - mydataset.add_results(x_results) + dataset.add_results(x_results) + + yparam = ParamSpec("y", "numeric") if N != M: - with pytest.raises(ValueError): - mydataset.add_parameter_values(ParamSpec("y", "numeric"), - [y for y in range(M)]) + match_str = f'Need to have {N} values but got {M}.' + match_str = re.escape(match_str) + with pytest.raises(ValueError, match=match_str): + dataset.add_parameter_values(yparam, [y for y in range(M)]) - mydataset.add_parameter_values(ParamSpec("y", "numeric"), - [y for y in range(N)]) + yvals = [y for y in range(N)] + y_expected = [[None]] * N + [[y] for y in yvals] # <-- should it have None? + dataset.add_parameter_values(yparam, yvals) - mydataset.mark_complete() + shadow_ds = make_shadow_dataset(dataset) + + try: + assert y_expected == dataset.get_data(yparam) + assert y_expected == shadow_ds.get_data(yparam) + + dataset.mark_complete() + + # and now let's test that dataset's connection does not commit anymore + # when `atomic` is used + dataset.add_results([{yparam.name: -2}]) + y_expected_2 = y_expected + [[-2]] + + assert y_expected_2 == dataset.get_data(yparam) + assert y_expected_2 == shadow_ds.get_data(yparam) + + finally: + shadow_ds.conn.close() @pytest.mark.usefixtures("dataset") diff --git a/qcodes/tests/dataset/test_subscribing.py b/qcodes/tests/dataset/test_subscribing.py index 42c8d478e93..8d862f7b332 100644 --- a/qcodes/tests/dataset/test_subscribing.py +++ b/qcodes/tests/dataset/test_subscribing.py @@ -13,6 +13,7 @@ from qcodes.tests.dataset.temporary_databases import ( empty_temp_db, experiment, dataset) # pylint: enable=unused-import +from qcodes.tests.dataset.test_dataset_basic import make_shadow_dataset from qcodes.tests.test_config import default_config from qcodes.tests.common import retry_until_does_not_throw @@ -196,3 +197,48 @@ def test_subscription_from_config_wrong_name(dataset): with pytest.raises(RuntimeError): sub_id_c = dataset.subscribe_from_config('test_subscriber') + +def test_unsubscribe_all_makes_atomic_connections_never_commit( + dataset, basic_subscriber): + xparam = ParamSpec(name='x', paramtype='numeric') + dataset.add_parameter(xparam) + + sub_id = dataset.subscribe(basic_subscriber, min_wait=0, min_count=1, + state={}) + + assert len(dataset.subscribers) == 1 + assert list(dataset.subscribers.keys()) == [sub_id] + + dataset.unsubscribe_all() + + dataset.add_result({'x': 1}) + + shadow_ds = make_shadow_dataset(dataset) + try: + assert dataset.get_data('x') == [[1]] + assert shadow_ds.get_data('x') == [[1]] + finally: + shadow_ds.conn.close() + + +def test_unsubscribe_makes_atomic_connections_never_commit( + dataset, basic_subscriber): + xparam = ParamSpec(name='x', paramtype='numeric') + dataset.add_parameter(xparam) + + sub_id = dataset.subscribe(basic_subscriber, min_wait=0, min_count=1, + state={}) + + assert len(dataset.subscribers) == 1 + assert list(dataset.subscribers.keys()) == [sub_id] + + dataset.unsubscribe(sub_id) + + dataset.add_result({'x': 1}) + + shadow_ds = make_shadow_dataset(dataset) + try: + assert dataset.get_data('x') == [[1]] + assert shadow_ds.get_data('x') == [[1]] + finally: + shadow_ds.conn.close() From dcdd8cf8d01b095dba71f1c992d57610a34c477f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 19 Nov 2018 12:52:54 -0800 Subject: [PATCH 132/719] initial commit --- .../Qcodes example with Stahl.ipynb | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/examples/driver_examples/Qcodes example with Stahl.ipynb diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb new file mode 100644 index 00000000000..8d079ed6513 --- /dev/null +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -0,0 +1,110 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes import VisaInstrument " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#stahl = VisaInstrument(\"stahl\", \"COM3\")" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import visa\n", + "rm = visa.ResourceManager(visa_library=r\"C:\\Windows\\SysWOW64\\visa32.dll\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "#rm.open_resource(\"COM3\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'Serial'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0mSerial\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'Serial'" + ] + } + ], + "source": [ + "import Serial " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "()" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rm.list_resources()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 0de01219c057cae37bd8d19804f22993096a1438 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 12:13:17 +0100 Subject: [PATCH 133/719] Deprecate DataSet.modify_result, to be removed soon "it's a fundamentally flawed idea" --- qcodes/dataset/data_set.py | 2 ++ qcodes/tests/dataset/test_dataset_basic.py | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 490cb3c6bd1..c63f165e3fb 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -576,6 +576,8 @@ def add_results(self, results: List[Dict[str, VALUE]]) -> int: values) return len_before_add + @deprecate(reason='it is an experimental functionality, and is most ' + 'probably will be removed soon.') def modify_result(self, index: int, results: Dict[str, VALUES]) -> None: """ Modify a logically single result of existing parameters diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 069378f3d63..8a40e0b3171 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -390,28 +390,29 @@ def test_modify_result(): assert (shadow_ds.get_data('z')[0][0] == zdata).all() with pytest.raises(ValueError): - dataset.modify_result(0, {' x': 1}) + pytest.deprecated_call( + dataset.modify_result, 0, {' x': 1}) xdata = 1 ydata = 12 zdata = np.linspace(0, 1, 99) - dataset.modify_result(0, {'x': xdata}) + pytest.deprecated_call(dataset.modify_result, 0, {'x': xdata}) assert dataset.get_data('x')[0][0] == xdata assert shadow_ds.get_data('x')[0][0] == xdata - dataset.modify_result(0, {'y': ydata}) + pytest.deprecated_call(dataset.modify_result, 0, {'y': ydata}) assert dataset.get_data('y')[0][0] == ydata assert shadow_ds.get_data('y')[0][0] == ydata - dataset.modify_result(0, {'z': zdata}) + pytest.deprecated_call(dataset.modify_result, 0, {'z': zdata}) assert (dataset.get_data('z')[0][0] == zdata).all() assert (shadow_ds.get_data('z')[0][0] == zdata).all() dataset.mark_complete() with pytest.raises(CompletedError): - dataset.modify_result(0, {'x': 2}) + pytest.deprecated_call(dataset.modify_result, 0, {'x': 2}) finally: shadow_ds.conn.close() From 7cf0d9969e1f28cb5b011410353934b205b2caf6 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 31 Oct 2018 22:05:03 +0100 Subject: [PATCH 134/719] min and max is allowed to be None --- qcodes/utils/validators.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/utils/validators.py b/qcodes/utils/validators.py index 15bd4d658b1..e7ff3d827fc 100644 --- a/qcodes/utils/validators.py +++ b/qcodes/utils/validators.py @@ -31,7 +31,8 @@ def validate_all(*args, context: str='') -> None: validator.validate(value, 'argument ' + str(i) + context) -def range_str(min_val: Union[float, int], max_val: Union[float, int], +def range_str(min_val: Optional[Union[float, int]], + max_val: Optional[Union[float, int]], name: str) -> str: """ utility to represent ranges in Validator repr's From 61bbfc599ad715a12809176760751fdd72734cde Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 31 Oct 2018 22:19:19 +0100 Subject: [PATCH 135/719] Config fix mypy strict issues --- qcodes/config/config.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 1b1de22b53b..fcdda742f2a 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -9,7 +9,7 @@ from pathlib import Path import jsonschema -from typing import Dict +from typing import Dict, Tuple logger = logging.getLogger(__name__) @@ -102,7 +102,7 @@ def __init__(self, path: str=None) -> None: self.defaults, self.defaults_schema = self.load_default() self.update_config() - def load_default(self): + def load_default(self) -> Tuple[dict, dict]: defaults = self.load_config(self.default_file_name) defaults_schema = self.load_config(self.schema_default_file_name) self.validate(defaults, defaults_schema) @@ -156,7 +156,9 @@ def update_config(self, path: str=None) -> dict: schema_file = os.path.join(self.config_file_path, self.schema_file_name) self._update_config_from_file(config_file, schema_file, config) - + if config is None: + raise RuntimeError("Could not load config from any of the " + "expected locations.") self.current_config = config self.current_config_path = self._loaded_config_files[-1] From 44b7d0135192f0b5bf7d532128c40490a579bde4 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 31 Oct 2018 22:19:45 +0100 Subject: [PATCH 136/719] Ensure that lhandler is not None --- qcodes/logger/logger.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/logger/logger.py b/qcodes/logger/logger.py index 809a09a294d..f6d5315c083 100644 --- a/qcodes/logger/logger.py +++ b/qcodes/logger/logger.py @@ -240,6 +240,8 @@ def console_level(level: LevelType): level: level to set the console handler to """ global console_handler + if console_handler is None: + raise RuntimeError("Console handler is None") with handler_level(level, handler=console_handler): yield From 58aeb63619e1d1e84d357b08fc3c0f337845b418 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 31 Oct 2018 22:20:07 +0100 Subject: [PATCH 137/719] This cannot be optional --- qcodes/utils/log_analysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/utils/log_analysis.py b/qcodes/utils/log_analysis.py index dfa9a7ef920..e8c809c710b 100644 --- a/qcodes/utils/log_analysis.py +++ b/qcodes/utils/log_analysis.py @@ -10,7 +10,7 @@ @deprecate(reason="The logging infrastructure has moved to `qcodes.utils.logger`", alternative="`qcodes.utils.logger.logfile_to_dataframe`") -def logfile_to_dataframe(logfile: Optional[str]=None, +def logfile_to_dataframe(logfile: str, columns: Optional[List[str]]=None, separator: Optional[str]=None) -> pd.DataFrame: From 707cfc7d57f95eea7c66e8686ed4cc1dbb398e27 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 08:33:30 +0100 Subject: [PATCH 138/719] Improve optional typing --- qcodes/dataset/measurements.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 4e8e47baefb..f200dca02ba 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -533,7 +533,7 @@ def __init__(self, exp: Optional[Experiment] = None, self.name = '' @property - def write_period(self) -> float: + def write_period(self) -> Optional[float]: return self._write_period @write_period.setter @@ -650,10 +650,10 @@ def register_parameter( return self def _register_parameter(self : T, name: str, - label: str, - unit: str, - setpoints: setpoints_type, - basis: setpoints_type, + label: Optional[str], + unit: Optional[str], + setpoints: Optional[setpoints_type], + basis: Optional[setpoints_type], paramtype: str) -> T: """ Generate ParamSpecs and register them for an individual parameter @@ -688,8 +688,8 @@ def _register_parameter(self : T, name: str, def _register_arrayparameter(self, parameter: ArrayParameter, - setpoints: setpoints_type, - basis: setpoints_type, + setpoints: Optional[setpoints_type], + basis: Optional[setpoints_type], paramtype: str, ) -> None: """ Register an Array paramter and the setpoints belonging to the @@ -728,8 +728,8 @@ def _register_arrayparameter(self, def _register_multiparameter(self, multiparameter: MultiParameter, - setpoints: setpoints_type, - basis: setpoints_type, + setpoints: Optional[setpoints_type], + basis: Optional[setpoints_type], paramtype: str) -> None: """ Find the individual multiparameter components and their setpoints From 2f065067f29652a420020c1fe1c92f21c30daad7 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 08:38:35 +0100 Subject: [PATCH 139/719] Clarify types --- qcodes/utils/plotting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/utils/plotting.py b/qcodes/utils/plotting.py index 20a9b53047a..292fbf91b0c 100644 --- a/qcodes/utils/plotting.py +++ b/qcodes/utils/plotting.py @@ -146,7 +146,7 @@ def apply_color_scale_limits(colorbar: matplotlib.pyplot.colorbar, raise RuntimeError('You may not specify `data_lim` and `data_array` ' 'at the same time. Please refer to the docstring of ' '`apply_color_scale_limits for details:\n\n`' - + apply_color_scale_limits.__doc__) + + str(apply_color_scale_limits.__doc__)) else: data_lim = cast(Tuple[float, float], tuple(sorted(data_lim))) # if `None` is provided in the new limits don't change this limit @@ -173,8 +173,8 @@ def apply_color_scale_limits(colorbar: matplotlib.pyplot.colorbar, def apply_auto_color_scale(colorbar: matplotlib.pyplot.colorbar, data_array: Optional[np.ndarray]=None, - cutoff_percentile: Optional[Union[Tuple[ - Number, Number], Number]]=DEFAULT_PERCENTILE, + cutoff_percentile: Union[Tuple[ + Number, Number], Number]=DEFAULT_PERCENTILE, color_over: Optional[Any]=DEFAULT_COLOR_OVER, color_under: Optional[Any]=DEFAULT_COLOR_UNDER ) -> None: From cbefa2cbb4098644638a47057edeb46b43562b51 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 08:45:41 +0100 Subject: [PATCH 140/719] Strict optional for ATS --- qcodes/instrument_drivers/AlazarTech/ATS.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/AlazarTech/ATS.py b/qcodes/instrument_drivers/AlazarTech/ATS.py index 9078d7d9d20..efc04727315 100644 --- a/qcodes/instrument_drivers/AlazarTech/ATS.py +++ b/qcodes/instrument_drivers/AlazarTech/ATS.py @@ -250,7 +250,6 @@ def get_board_info(cls, dll: ctypes.CDLL, system_id: int, def __init__(self, name: str, system_id: int=1, board_id: int=1, dll_path: str=None, **kwargs) -> None: super().__init__(name, **kwargs) - self._ATS_dll = None if os.name == 'nt': self._ATS_dll = ctypes.cdll.LoadLibrary(dll_path or self.dll_path) @@ -886,7 +885,10 @@ def _call_dll(self, func_name: str, *args) -> None: update_params: List[Parameter] = [] for arg in args: if isinstance(arg, Parameter): - args_out.append(arg.raw_value) + if arg.raw_value is not None: + args_out.append(arg.raw_value) + else: + raise RuntimeError(f"{arg} has value None") update_params.append(arg) else: args_out.append(arg) From 3aebba0580189b74a3915293b4bae7b957a1bdf2 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 14:07:56 +0100 Subject: [PATCH 141/719] Match baseclass signature --- qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py index a1784036ad0..0ea28b4fd89 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py @@ -1,7 +1,7 @@ import logging import struct import numpy as np -from typing import List, Dict +from typing import List, Dict, Optional import qcodes as qc from qcodes import VisaInstrument, DataSet @@ -430,7 +430,7 @@ def __init__(self, name: str, address: str, **kwargs) -> None: def _display_settext(self, text: str) -> None: self.visa_handle.write('display.settext("{}")'.format(text)) - def get_idn(self) -> Dict[str, str]: + def get_idn(self) -> Dict[str, Optional[str]]: IDN = self.ask_raw('*IDN?') vendor, model, serial, firmware = map(str.strip, IDN.split(',')) model = model[6:] From e7284144ced22d28dcf22b13b139839b26de9168 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 14:08:18 +0100 Subject: [PATCH 142/719] g could be none --- qcodes/tests/drivers/test_ami430.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/tests/drivers/test_ami430.py b/qcodes/tests/drivers/test_ami430.py index 9d7cff55038..65485cc14c2 100644 --- a/qcodes/tests/drivers/test_ami430.py +++ b/qcodes/tests/drivers/test_ami430.py @@ -253,6 +253,8 @@ def get_ramp_down_order(messages: List[str]) -> List[str]: continue g = re.search(r"\[(.*).*\] Writing: CONF:FIELD:TARG", msg) + if g is None: + raise RuntimeError("No match is found") name = g.groups()[0] order.append(name) From b715bdf55cb03ec523e4e3487e398df2ace4cf90 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 15:09:36 +0100 Subject: [PATCH 143/719] Signal hound strict optional --- .../instrument_drivers/signal_hound/USB_SA124B.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py index 01f24221d51..23b1be9823e 100644 --- a/qcodes/instrument_drivers/signal_hound/USB_SA124B.py +++ b/qcodes/instrument_drivers/signal_hound/USB_SA124B.py @@ -140,12 +140,15 @@ def set_sweep(self, sweep_len: int, start_freq: number, self.instrument._trace_updated = True def get_raw(self) -> np.ndarray: + if self.instrument is None: + raise RuntimeError("No instrument is attached to" + "'FrequencySweep'") if not isinstance(self.instrument, SignalHound_USB_SA124B): raise RuntimeError("'FrequencySweep' is only implemented" "for 'SignalHound_USB_SA124B'") if not self.instrument._trace_updated: raise RuntimeError('trace not updated, run configure to update') - data = self._instrument._get_averaged_sweep_data() + data = self.instrument._get_averaged_sweep_data() sleep(2*self.instrument.sleep_time.get()) return data @@ -409,6 +412,7 @@ def sync_parameters(self) -> None: # the third argument to saInitiate is a flag that is # currently not used err = self.dll.saInitiate(self.deviceHandle, mode, 0) + extrainfo: Optional[str] = None if err == saStatus.saInvalidParameterErr: extrainfo = """ In real-time mode, this value may be returned if the span @@ -425,8 +429,6 @@ def sync_parameters(self) -> None: """ elif err == saStatus.saBandwidthErr: extrainfo = 'RBW is larger than your span. (Sweep Mode)!' - else: - extrainfo = None self.check_for_error(err, 'saInitiate', extrainfo) self._parameters_synced = True @@ -478,11 +480,11 @@ def abort(self) -> None: log.info('Stopping acquisition') err = self.dll.saAbort(self.deviceHandle) + extrainfo: Optional[str] = None if err == saStatus.saDeviceNotConfiguredErr: extrainfo = 'Device was already idle! Did you call abort ' \ 'without ever calling initiate()' - else: - extrainfo = None + self.check_for_error(err, 'saAbort', extrainfo) def preset(self) -> None: @@ -640,7 +642,7 @@ def check_for_error(err: int, source: str, extrainfo: str=None) -> None: log.info(msg) def get_idn(self) -> Dict[str, Optional[str]]: - output = {} + output: Dict[str, Optional[str]] = {} output['vendor'] = 'Signal Hound' output['model'] = self._get_device_type() serialnumber = ct.c_int32() From 46329ecbd01485863c2d281889738606b69faa64 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 15:19:16 +0100 Subject: [PATCH 144/719] Mercury strict typing --- qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py index 0ad60dac98e..811d3fa6057 100644 --- a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py +++ b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py @@ -213,7 +213,9 @@ class MercuryiPS(VisaInstrument): """ def __init__(self, name: str, address: str, visalib=None, - field_limits: Optional[Callable]=None, + field_limits: Optional[Callable[[float, + float, + float], bool]]=None, **kwargs) -> None: """ Args: @@ -306,8 +308,8 @@ def _set_target(self, coordinate: str, target: float) -> None: valid_vec = FieldVector() valid_vec.copy(self._target_vector) valid_vec.set_component(**{coordinate: target}) - - if not self._field_limits(*valid_vec.get_components('x', 'y', 'z')): + components = valid_vec.get_components('x', 'y', 'z') + if not self._field_limits(*components): raise ValueError(f'Cannot set {coordinate} target to {target}, ' 'that would violate the field_limits. ') From 518f01c4eef18a3dc4d872c3bd9d0d0ada7347ec Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 15:29:30 +0100 Subject: [PATCH 145/719] Correct strict typing in dataset --- qcodes/dataset/data_set.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 7f93402a935..802ceeeae8a 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -372,7 +372,7 @@ def completed_timestamp_raw(self) -> Union[float, None]: return get_completed_timestamp_from_run_id(self.conn, self.run_id) def completed_timestamp(self, - fmt: str="%Y-%m-%d %H:%M:%S") -> Union[str, None]: + fmt: str="%Y-%m-%d %H:%M:%S") -> Optional[str]: """ Returns timestamp when measurement run was completed in a human-readable format @@ -384,7 +384,7 @@ def completed_timestamp(self, completed_timestamp_raw = self.completed_timestamp_raw if completed_timestamp_raw: - completed_timestamp = time.strftime( + completed_timestamp: Optional[str] = time.strftime( fmt, time.localtime(completed_timestamp_raw)) else: completed_timestamp = None From 6c511fc6a37157046d864ff605f5ea7efbfab7ba Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 15:42:35 +0100 Subject: [PATCH 146/719] use python 3.6 syntax and add a needed cast for strict optional --- qcodes/instrument/base.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument/base.py b/qcodes/instrument/base.py index cce4e5f1d13..fc6912bef9c 100644 --- a/qcodes/instrument/base.py +++ b/qcodes/instrument/base.py @@ -120,7 +120,9 @@ def add_function(self, name: str, **kwargs) -> None: func = Function(name=name, instrument=self, **kwargs) self.functions[name] = func - def add_submodule(self, name: str, submodule: Union['InstrumentBase', 'ChannelList']) -> None: + def add_submodule(self, name: str, + submodule: Union['InstrumentBase', + 'ChannelList']) -> None: """ Bind one submodule to this instrument. @@ -401,9 +403,9 @@ class Instrument(InstrumentBase): shared_kwargs = () - _all_instruments = {} # type: Dict[str, weakref.ref[Instrument]] + _all_instruments: Dict[str, weakref.ref] = {} _type = None - _instances = [] # type: List[weakref.ref] + _instances: List[weakref.ref] = [] def __init__(self, name: str, metadata: Optional[Dict]=None, **kwargs) -> None: @@ -440,7 +442,7 @@ def get_idn(self) -> Dict[str, Optional[str]]: idstr = self.ask('*IDN?') # form is supposed to be comma-separated, but we've seen # other separators occasionally - idparts = [] # type: List[Optional[str]] + idparts: List[Optional[str]] = [] for separator in ',;:': # split into no more than 4 parts, so we don't lose info idparts = [p.strip() for p in idstr.split(separator, 3)] @@ -628,7 +630,7 @@ def find_instrument(cls, name: str, 'Instrument {} is {} but {} was requested'.format( name, type(ins), instrument_class)) - return ins + return cast('Instrument', ins) @staticmethod def exist(name: str, instrument_class: Optional[type]=None) -> bool: From d69eccf38d2657493fa80ba689ad7c76e6a2dd30 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 1 Nov 2018 15:43:15 +0100 Subject: [PATCH 147/719] Experiment container strict optional --- qcodes/dataset/experiment_container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index 36ccdc69dcd..4c1ce52f751 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -186,7 +186,7 @@ def experiments()->List[Experiment]: def new_experiment(name: str, sample_name: str, - format_string: Optional[str] = "{}-{}-{}") -> Experiment: + format_string: str = "{}-{}-{}") -> Experiment: """ Create a new experiment (in the database file from config) @@ -306,7 +306,7 @@ def load_or_create_experiment(experiment_name: str, try: experiment = load_experiment_by_name(experiment_name, sample_name) except ValueError as exception: - if "Experiment not found" in str(exception): + if "Experiment not found" in str(exception) and sample_name is not None: experiment = new_experiment(experiment_name, sample_name) else: raise exception From 41f82f986f9203253251fb14385d2883c0b8447e Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:05:10 +0100 Subject: [PATCH 148/719] Add abstract method helper --- qcodes/utils/helpers.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index 53757b65288..9980d4d94e4 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -654,3 +654,16 @@ def inner(**inner_kwargs): inner.__doc__ = docstring return inner + + +def abstractmethod(funcobj): + """A decorator indicating abstract methods. + + This is heavily inspired by the decorator of the same name in + the ABC standard library. But we make our own version because + we actually want to allow the class with the abstract method to be + instantiated and we will use this property to detect if the + method is abstract and should be overwritten. + """ + funcobj.__qcodesisabstractmethod__ = True + return funcobj From ab06ee9fc034c47fc14fc933ae3baa812c949be1 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:06:45 +0100 Subject: [PATCH 149/719] Make get_raw/set_raw abstract methods so that typing is consistent with subclasses --- qcodes/instrument/parameter.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 1de617b086f..94b603eae5f 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -65,7 +65,7 @@ Dict, Any, Sized, Iterable, cast, Type from functools import partial, wraps import numpy - +from qcodes.utils.helpers import abstractmethod from qcodes.utils.helpers import (permissive_range, is_sequence_of, DelegateAttributes, full_class, named_repr, @@ -182,8 +182,6 @@ class _BaseParameter(Metadatable): metadata (Optional[dict]): extra information to include with the JSON snapshot of the parameter """ - get_raw = None # type: Optional[Callable] - set_raw = None # type: Optional[Callable] def __init__(self, name: str, instrument: Optional['Instrument'], @@ -242,14 +240,14 @@ def __init__(self, name: str, self._latest = {'value': None, 'ts': None, 'raw_value': None} self.get_latest = GetLatest(self, max_val_age=max_val_age) - if hasattr(self, 'get_raw') and self.get_raw is not None: + if hasattr(self, 'get_raw') and not getattr(self.get_raw, '__qcodesisabstractmethod__', False): self.get = self._wrap_get(self.get_raw) elif hasattr(self, 'get'): warnings.warn('Wrapping get method, original get method will not ' 'be directly accessible. It is recommended to ' 'define get_raw in your subclass instead.' ) self.get = self._wrap_get(self.get) - if hasattr(self, 'set_raw') and self.set_raw is not None: + if hasattr(self, 'set_raw') and not getattr(self.set_raw, '__qcodesisabstractmethod__', False): self.set = self._wrap_set(self.set_raw) elif hasattr(self, 'set'): warnings.warn('Wrapping set method, original set method will not ' @@ -266,6 +264,14 @@ def __init__(self, name: str, # check if additional waiting time is needed before next set self._t_last_set = time.perf_counter() + @abstractmethod + def get_raw(self): + raise NotImplementedError + + @abstractmethod + def set_raw(self, value): + raise NotImplementedError + def __str__(self): """Include the instrument name with the Parameter name if possible.""" inst_name = getattr(self._instrument, 'name', '') From 36b309cbf630adf457ee5d8717e396a3473a1db3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:07:22 +0100 Subject: [PATCH 150/719] add a few none checks to make mypy happy in strict optional --- qcodes/instrument_drivers/Keysight/N52xx.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qcodes/instrument_drivers/Keysight/N52xx.py b/qcodes/instrument_drivers/Keysight/N52xx.py index af52202372d..d53db1e3744 100644 --- a/qcodes/instrument_drivers/Keysight/N52xx.py +++ b/qcodes/instrument_drivers/Keysight/N52xx.py @@ -34,6 +34,9 @@ def shape(self, val: Sequence[int]) -> None: @property # type: ignore def setpoints(self) -> Sequence: # type: ignore + if self._instrument is None: + raise RuntimeError("Cannot return setpoints if not attached " + "to instrument") start = self._instrument.root_instrument.start() stop = self._instrument.root_instrument.stop() return (np.linspace(start, stop, self.shape[0]),) @@ -65,6 +68,8 @@ def __init__(self, self.memory = memory def get_raw(self) -> Sequence[float]: + if self._instrument is None: + raise RuntimeError("Cannot get data without instrument") root_instr = self._instrument.root_instrument # Check if we should run a new sweep if root_instr.auto_sweep(): From 3547602727494738d0d8b83cd364521eb1037728 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:18:27 +0100 Subject: [PATCH 151/719] Make mypy strict happy in logger --- qcodes/logger/instrument_logger.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/qcodes/logger/instrument_logger.py b/qcodes/logger/instrument_logger.py index 059aaffd8db..b3fe82beca8 100644 --- a/qcodes/logger/instrument_logger.py +++ b/qcodes/logger/instrument_logger.py @@ -1,6 +1,6 @@ from contextlib import contextmanager import logging -from typing import Optional, Sequence, Union, TYPE_CHECKING +from typing import Optional, Sequence, Union, TYPE_CHECKING, cast import collections.abc from .logger import get_console_handler, LevelType, handler_level if TYPE_CHECKING: @@ -103,20 +103,27 @@ def filter_instrument(instrument: Union['InstrumentBase', level: level to set the handlers to handler: single or sequence of handlers which to change """ + handler_int: Sequence[logging.Handler] if handler is None: - handler = (get_console_handler(),) - if not isinstance(handler, collections.abc.Sequence): - handler = (handler,) + myhandler = get_console_handler() + if myhandler is None: + raise RuntimeError("Trying to filter instrument but no handler " + "defined. Did you call `start_logger`") + handler_int = (myhandler,) + elif not isinstance(handler, collections.abc.Sequence): + handler_int = (handler,) + else: + handler_int = handler instrument_filter = InstrumentFilter(instrument) - for h in handler: + for h in handler_int: h.addFilter(instrument_filter) try: if level is not None: - with handler_level(level, handler): + with handler_level(level, handler_int): yield else: yield finally: - for h in handler: + for h in handler_int: h.removeFilter(instrument_filter) From f595ffde11311736de44f0be9f579869ed6aeace Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:29:28 +0100 Subject: [PATCH 152/719] Add some checks for none to group parameter --- qcodes/instrument/group_parameter.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument/group_parameter.py b/qcodes/instrument/group_parameter.py index 8d7b5e4baac..31d67bfca54 100644 --- a/qcodes/instrument/group_parameter.py +++ b/qcodes/instrument/group_parameter.py @@ -54,10 +54,12 @@ def __init__(self, self.get = self._wrap_get(self.get_raw) def _get_raw_value(self) -> Any: + if self.group is None: + raise RuntimeError("Trying to get Group value but no " + "group defined") self.group.update() return self.raw_value - class Group: """ The group combines `GroupParameter`s that are to be gotten or set via the @@ -190,7 +192,12 @@ def set(self, set_parameter: GroupParameter, value: Any): calling_dict = {name: p.raw_value for name, p in self.parameters.items()} calling_dict[set_parameter.name] = value + if self.set_cmd is None: + raise RuntimeError("Calling set but no `set_cmd` defined") command_str = self.set_cmd.format(**calling_dict) + if self.instrument is None: + raise RuntimeError("Trying to set GroupParameter not attached " + "to any instrument.") self.instrument.write(command_str) def update(self): From 39c8c1cd7a2271a3258c8fab0629a954f32abe0c Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:36:10 +0100 Subject: [PATCH 153/719] Make set_raw check if the group is None to make mypy happy --- qcodes/instrument/group_parameter.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument/group_parameter.py b/qcodes/instrument/group_parameter.py index 31d67bfca54..907a3cdbfbb 100644 --- a/qcodes/instrument/group_parameter.py +++ b/qcodes/instrument/group_parameter.py @@ -45,7 +45,6 @@ def __init__(self, self.group: Union[Group, None] = None super().__init__(name, instrument=instrument, **kwargs) - self.set_raw = lambda value: self.group.set(self, value) self.set = self._wrap_set(self.set_raw) self.get_raw = lambda result=None: result if result is not None \ @@ -60,6 +59,13 @@ def _get_raw_value(self) -> Any: self.group.update() return self.raw_value + def set_raw(self, value: Any) -> None: + if self.group is None: + raise RuntimeError("Trying to get Group value but no " + "group defined") + self.group.set(self, value) + + class Group: """ The group combines `GroupParameter`s that are to be gotten or set via the From 47ef0f7b85a0c07af0647cefd8acef2523532e00 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 2 Nov 2018 16:36:35 +0100 Subject: [PATCH 154/719] Check that setpoints are not None before using them --- qcodes/dataset/measurements.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index f200dca02ba..82887a5c91a 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -283,6 +283,9 @@ def _unbundle_arrayparameter(self, """ sp_names = parameter.setpoint_full_names fallback_sp_name = f"{parameter.full_name}_setpoint" + if parameter.setpoints is None: + raise RuntimeError(f"{parameter.full_name} is an {type(parameter)} " + f"without setpoints. Cannot handle this.") self._unbundle_setpoints_from_param(parameter, sp_names, fallback_sp_name, parameter.setpoints, @@ -358,6 +361,9 @@ def _unbundle_multiparameter(self, found_parameters: The list of all parameters that we know of by now This is modified in place with new parameters found here. """ + if parameter.setpoints is None: + raise RuntimeError(f"{parameter.full_name} is an {type(parameter)} " + f"without setpoints. Cannot handle this.") for i in range(len(parameter.shapes)): shape = parameter.shapes[i] res.append((parameter.names[i], data[i])) From f809449c0c80de5f647110db18aac9546d5f0828 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 5 Nov 2018 13:59:57 +0100 Subject: [PATCH 155/719] Should now be passing with strict optional --- mypy.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy.ini b/mypy.ini index 2b38716299c..ef6027adb92 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -strict_optional = False +strict_optional = True disallow_untyped_decorators = True ignore_missing_imports = True From 3e8f06470b504bd8a4fc275a8fd430b69cb5aa95 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 12:41:48 +0100 Subject: [PATCH 156/719] Update qcodes/tests/drivers/test_ami430.py Co-Authored-By: jenshnielsen --- qcodes/tests/drivers/test_ami430.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/drivers/test_ami430.py b/qcodes/tests/drivers/test_ami430.py index 65485cc14c2..dde781af72e 100644 --- a/qcodes/tests/drivers/test_ami430.py +++ b/qcodes/tests/drivers/test_ami430.py @@ -254,7 +254,7 @@ def get_ramp_down_order(messages: List[str]) -> List[str]: g = re.search(r"\[(.*).*\] Writing: CONF:FIELD:TARG", msg) if g is None: - raise RuntimeError("No match is found") + raise RuntimeError(f"No match found in {msg!r} when getting ramp down order") name = g.groups()[0] order.append(name) From b5ec215cce9c7d8475e8967267bc0112545dc2f6 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 12:41:57 +0100 Subject: [PATCH 157/719] Update qcodes/utils/helpers.py Co-Authored-By: jenshnielsen --- qcodes/utils/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index 9980d4d94e4..40aa3502df6 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -665,5 +665,5 @@ def abstractmethod(funcobj): instantiated and we will use this property to detect if the method is abstract and should be overwritten. """ - funcobj.__qcodesisabstractmethod__ = True + funcobj.__qcodes_is_abstract_method__ = True return funcobj From 9f7d02543f0e088fb3c54d6786f9db4458d83eb9 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 12:49:05 +0100 Subject: [PATCH 158/719] Update qcodes/logger/instrument_logger.py Co-Authored-By: jenshnielsen --- qcodes/logger/instrument_logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/logger/instrument_logger.py b/qcodes/logger/instrument_logger.py index b3fe82beca8..fffddc4300f 100644 --- a/qcodes/logger/instrument_logger.py +++ b/qcodes/logger/instrument_logger.py @@ -108,7 +108,7 @@ def filter_instrument(instrument: Union['InstrumentBase', myhandler = get_console_handler() if myhandler is None: raise RuntimeError("Trying to filter instrument but no handler " - "defined. Did you call `start_logger`") + "defined. Did you forget to call `start_logger` before?") handler_int = (myhandler,) elif not isinstance(handler, collections.abc.Sequence): handler_int = (handler,) From fa89d2ef39c44d05d3af36ba873208b416a0ef48 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 12:45:16 +0100 Subject: [PATCH 159/719] change name here too --- qcodes/instrument/parameter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 94b603eae5f..5b3a7b76959 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -240,19 +240,19 @@ def __init__(self, name: str, self._latest = {'value': None, 'ts': None, 'raw_value': None} self.get_latest = GetLatest(self, max_val_age=max_val_age) - if hasattr(self, 'get_raw') and not getattr(self.get_raw, '__qcodesisabstractmethod__', False): + if hasattr(self, 'get_raw') and not getattr(self.get_raw, '__qcodes_is_abstract_method__', False): self.get = self._wrap_get(self.get_raw) elif hasattr(self, 'get'): warnings.warn('Wrapping get method, original get method will not ' 'be directly accessible. It is recommended to ' - 'define get_raw in your subclass instead.' ) + 'define get_raw in your subclass instead.') self.get = self._wrap_get(self.get) - if hasattr(self, 'set_raw') and not getattr(self.set_raw, '__qcodesisabstractmethod__', False): + if hasattr(self, 'set_raw') and not getattr(self.set_raw, '__qcodes_is_abstract_method__', False): self.set = self._wrap_set(self.set_raw) elif hasattr(self, 'set'): warnings.warn('Wrapping set method, original set method will not ' 'be directly accessible. It is recommended to ' - 'define set_raw in your subclass instead.' ) + 'define set_raw in your subclass instead.') self.set = self._wrap_set(self.set) # subclasses should extend this list with extra attributes they From 39edc4ae1455bde0e5a098cb8f8c85e98e1694f3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 12:47:57 +0100 Subject: [PATCH 160/719] allow sample_name to be None --- qcodes/dataset/experiment_container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index 4c1ce52f751..1d2100f6257 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -185,7 +185,7 @@ def experiments()->List[Experiment]: def new_experiment(name: str, - sample_name: str, + sample_name: Optional[str], format_string: str = "{}-{}-{}") -> Experiment: """ Create a new experiment (in the database file from config) @@ -306,7 +306,7 @@ def load_or_create_experiment(experiment_name: str, try: experiment = load_experiment_by_name(experiment_name, sample_name) except ValueError as exception: - if "Experiment not found" in str(exception) and sample_name is not None: + if "Experiment not found" in str(exception): experiment = new_experiment(experiment_name, sample_name) else: raise exception From a80319f53a7ad22ca0e87b9b916184b5426d3ebd Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 12:57:19 +0100 Subject: [PATCH 161/719] Handle the rare case that one of the snapshots is empty --- qcodes/utils/metadata.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/qcodes/utils/metadata.py b/qcodes/utils/metadata.py index 170be108ef1..495c9859393 100644 --- a/qcodes/utils/metadata.py +++ b/qcodes/utils/metadata.py @@ -87,9 +87,10 @@ def extract_param_values(snapshot: Snapshot) -> Dict[ParameterKey, Any]: return parameters + def diff_param_values(left_snapshot: Snapshot, right_snapshot: Snapshot - ) -> ParameterDiff: + ) -> ParameterDiff: """ Given two snapshots, returns the differences between parameter values in each. @@ -114,7 +115,8 @@ def diff_param_values(left_snapshot: Snapshot, } ) -def diff_param_values_by_id(left_id : RunId, right_id : RunId): + +def diff_param_values_by_id(left_id: RunId, right_id: RunId) -> ParameterDiff: """ Given the IDs of two datasets, returns the differences between parameter values in each of their snapshots. @@ -122,7 +124,13 @@ def diff_param_values_by_id(left_id : RunId, right_id : RunId): # Local import to reduce load time and # avoid circular references. from qcodes.dataset.data_set import load_by_id - return diff_param_values( - load_by_id(left_id).snapshot, - load_by_id(right_id).snapshot - ) + + left_snapshot = load_by_id(left_id).snapshot + right_snapshot = load_by_id(right_id).snapshot + + if left_snapshot is None or right_snapshot is None: + raise RuntimeError(f"Tried to compare {left_snapshot} " + f"and {right_snapshot}" + f"but on of them is empty") + + return diff_param_values(left_snapshot, right_snapshot) From 67702912344e93f417b7817079950ba5b9898c54 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 13:01:39 +0100 Subject: [PATCH 162/719] This class cannot handle a missing parent --- qcodes/tests/test_autoloadable_channels.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/tests/test_autoloadable_channels.py b/qcodes/tests/test_autoloadable_channels.py index e7b9d913b6f..aa8290d0375 100644 --- a/qcodes/tests/test_autoloadable_channels.py +++ b/qcodes/tests/test_autoloadable_channels.py @@ -129,6 +129,8 @@ def _get_new_instance_kwargs( Find the smallest channel number not yet occupied. An optional keyword `greeting` is extracted from the kwargs. The default is "Hello" """ + if parent is None: + raise RuntimeError("SimpleTestChannel needs a parent instrument") channels_str = parent.channel_catalog() existing_channels = [int(i) for i in channels_str.split(",")] From 9026d92bb13822b70af4cd510f3216a53df1be69 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 13:05:26 +0100 Subject: [PATCH 163/719] better variable name and fix some docstrings --- qcodes/logger/instrument_logger.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/qcodes/logger/instrument_logger.py b/qcodes/logger/instrument_logger.py index fffddc4300f..0bef73ce75e 100644 --- a/qcodes/logger/instrument_logger.py +++ b/qcodes/logger/instrument_logger.py @@ -100,30 +100,33 @@ def filter_instrument(instrument: Union['InstrumentBase', >>> v = dmm2.v() # not logged Args: + instrument: The instrument or sequence of instruments to enable + messages from. level: level to set the handlers to handler: single or sequence of handlers which to change """ - handler_int: Sequence[logging.Handler] + handlers: Sequence[logging.Handler] if handler is None: myhandler = get_console_handler() if myhandler is None: raise RuntimeError("Trying to filter instrument but no handler " - "defined. Did you forget to call `start_logger` before?") - handler_int = (myhandler,) + "defined. Did you forget to call " + "`start_logger` before?") + handlers = (myhandler,) elif not isinstance(handler, collections.abc.Sequence): - handler_int = (handler,) + handlers = (handler,) else: - handler_int = handler + handlers = handler instrument_filter = InstrumentFilter(instrument) - for h in handler_int: + for h in handlers: h.addFilter(instrument_filter) try: if level is not None: - with handler_level(level, handler_int): + with handler_level(level, handlers): yield else: yield finally: - for h in handler_int: + for h in handlers: h.removeFilter(instrument_filter) From e6560811e2ba817c576de3b66ff5120632bb1956 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 13:08:15 +0100 Subject: [PATCH 164/719] better message --- qcodes/logger/logger.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/logger/logger.py b/qcodes/logger/logger.py index f6d5315c083..fee0ea9c64a 100644 --- a/qcodes/logger/logger.py +++ b/qcodes/logger/logger.py @@ -234,14 +234,15 @@ def console_level(level: LevelType): handler. Example: >>> with logger.console_level(level=logging.DEBUG): - >>> root_logger.debug('this is now visible) + >>> root_logger.debug('this is now visible') Args: level: level to set the console handler to """ global console_handler if console_handler is None: - raise RuntimeError("Console handler is None") + raise RuntimeError("Console handler is None. Cannot set the level" + " on it") with handler_level(level, handler=console_handler): yield From b4d075ab11cee6cfb96e8bee3dc2c6f91db61a52 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 13:23:24 +0100 Subject: [PATCH 165/719] typo in error message --- qcodes/instrument/group_parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument/group_parameter.py b/qcodes/instrument/group_parameter.py index 907a3cdbfbb..88d84f03cb0 100644 --- a/qcodes/instrument/group_parameter.py +++ b/qcodes/instrument/group_parameter.py @@ -36,7 +36,7 @@ def __init__(self, name: str, instrument: Optional['Instrument'] = None, **kwargs - ) -> None: + ) -> None: if "set_cmd" in kwargs or "get_cmd" in kwargs: raise ValueError("A GroupParameter does not use 'set_cmd' or " @@ -61,7 +61,7 @@ def _get_raw_value(self) -> Any: def set_raw(self, value: Any) -> None: if self.group is None: - raise RuntimeError("Trying to get Group value but no " + raise RuntimeError("Trying to set Group value but no " "group defined") self.group.set(self, value) From cb13636506ecf8f138b045fdf3d39af1f203edd9 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 20 Nov 2018 13:41:01 +0100 Subject: [PATCH 166/719] Add tests for GroupParameter without group --- qcodes/tests/test_group_parameter.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qcodes/tests/test_group_parameter.py b/qcodes/tests/test_group_parameter.py index e001c5e8d2d..f8182bea134 100644 --- a/qcodes/tests/test_group_parameter.py +++ b/qcodes/tests/test_group_parameter.py @@ -77,3 +77,14 @@ def test_raise_on_get_set_cmd(): assert str(e.value) == "A GroupParameter does not use 'set_cmd' or " \ "'get_cmd' kwarg" + +def test_raises_on_get_set_without_group(): + param = GroupParameter(name='b') + + with pytest.raises(RuntimeError) as e: + param.get() + assert str(e.value) == "('Trying to get Group value but no group defined', 'getting b')" + + with pytest.raises(RuntimeError) as e: + param.set(1) + assert str(e.value) == "('Trying to set Group value but no group defined', 'setting b to 1')" From 5ea3fd27f84e0dadffc25a7dbfa0c33a48af9a31 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 16:24:07 +0100 Subject: [PATCH 167/719] Deprecate DataSet.add_parameter_values (doesnt work as expected) + test --- qcodes/dataset/data_set.py | 3 ++ qcodes/tests/dataset/test_dataset_basic.py | 63 ++++++++++++++++------ 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index c63f165e3fb..9d1d24e107b 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -653,6 +653,9 @@ def modify_results(self, start_index: int, flattened_keys, flattened_values) + @deprecate(reason='it is an experimental functionality, and it is not ' + 'known whether it will remain or it will be removed.', + alternative='add_parameter, add_result, add_results') def add_parameter_values(self, spec: ParamSpec, values: VALUES): """ Add a parameter to the DataSet and associates result values with the diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 8a40e0b3171..8e27ddd7e30 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -418,28 +418,61 @@ def test_modify_result(): shadow_ds.conn.close() -# @settings(max_examples=25, deadline=None) -# @given(N=hst.integers(min_value=1, max_value=10000), -# M=hst.integers(min_value=1, max_value=10000)) -# def test_add_parameter_values(dataset, N, M): -def test_add_parameter_values(dataset, N=2, M=3): +@pytest.mark.xfail(reason='This function does not seem to work the way its ' + 'docstring suggests. See the test body for more ' + 'information.') +def test_add_parameter_values(dataset): + n = 2 + m = n + 1 + xparam = ParamSpec('x', 'numeric') dataset.add_parameter(xparam) - x_results = [{'x': x} for x in range(N)] + x_results = [{'x': x} for x in range(n)] dataset.add_results(x_results) yparam = ParamSpec("y", "numeric") - if N != M: - match_str = f'Need to have {N} values but got {M}.' - match_str = re.escape(match_str) - with pytest.raises(ValueError, match=match_str): - dataset.add_parameter_values(yparam, [y for y in range(M)]) - - yvals = [y for y in range(N)] - y_expected = [[None]] * N + [[y] for y in yvals] # <-- should it have None? - dataset.add_parameter_values(yparam, yvals) + match_str = f'Need to have {n} values but got {m}.' + match_str = re.escape(match_str) + with pytest.raises(ValueError, match=match_str): + pytest.deprecated_call( + dataset.add_parameter_values, yparam, [y for y in range(m)]) + + yvals = [y for y in range(n)] + + # Unlike what the docstring of the method suggests, + # `add_parameter_values` does NOT add a new parameter and values for it + # "NEXT TO the columns of values of existing parameters". + # + # In other words, if the initial state of the table is: + # + # | x | + # -------- + # | 1 | + # | 2 | + # + # then the state of the table after calling `add_parameter_values` is + # going to be: + # + # | x | y | + # --------------- + # | 1 | NULL | + # | 2 | NULL | + # | NULL | 25 | + # | NULL | 42 | + # + # while the docstring suggests the following state: + # + # | x | y | + # --------------- + # | 1 | 25 | + # | 2 | 42 | + # + + y_expected = [[None]] * n + [[y] for y in yvals] + pytest.deprecated_call( + dataset.add_parameter_values, yparam, yvals) shadow_ds = make_shadow_dataset(dataset) From ae5cd997472f93996f05c40e4f9f09ddbb60678e Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 16:29:45 +0100 Subject: [PATCH 168/719] Fix bug for some DataSet methods making it not-committable afterwards List of methods: - unsubscribe - unsubscribe_all - modify_result - modify_results - add_parameter_values Note that ConnctionPlus still behaves weirdly. --- qcodes/dataset/sqlite_base.py | 2 + .../tests/dataset/test_sqlite_connection.py | 81 +++++++++++++++---- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 313593a49d9..3426cc2514f 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -746,6 +746,7 @@ def atomic(conn: SomeConnection): conn = make_plus_connection_from(conn) + old_atomic_in_progress = conn.atomic_in_progress is_outmost = not(conn.atomic_in_progress) conn.atomic_in_progress = True @@ -770,6 +771,7 @@ def atomic(conn: SomeConnection): finally: if is_outmost: conn.isolation_level = old_level + conn.atomic_in_progress = old_atomic_in_progress def make_plus_connection_from(conn: SomeConnection) -> ConnectionPlus: diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index e8e1e04fa21..5b66ad5661e 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -30,13 +30,13 @@ def sqlite_conn_is_idle(conn: sqlite3.Connection, isolation=None): def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): assert isinstance(conn, ConnectionPlus) - # assert False is conn.atomic_in_progress <-- should it be? - assert True is conn.atomic_in_progress + assert False is conn.atomic_in_progress assert isolation == conn.isolation_level assert False is conn.in_transaction return True +@pytest.mark.xfail('this test showcases a weird behavior of `ConnectionPlus`') def test_connection_plus(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -81,6 +81,8 @@ def test_atomic_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn, isolation_level) +@pytest.mark.xfail('this test showcases a weird behavior of `atomic`, ' + 'needs fixes, apparently also for `ConnectionPlus`') def test_atomic_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -137,6 +139,8 @@ def test_two_atomics_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn_2, isolation_level) +@pytest.mark.xfail('this test showcases a weird behavior of `atomic`, ' + 'needs fixes, apparently also for `ConnectionPlus`') def test_two_atomics_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -146,29 +150,72 @@ def test_two_atomics_on_outmost_plus_connection(): assert False is plus_conn.in_transaction with atomic(plus_conn) as atomic_conn_1: - # assert plus_conn_in_transaction(plus_conn) - assert plus_conn_is_idle(plus_conn, isolation_level) - # assert plus_conn_in_transaction(atomic_conn_1) - assert plus_conn_is_idle(atomic_conn_1, isolation_level) + # assert plus_conn_in_transaction(plus_conn) <-- should it be? + assert isinstance(plus_conn, ConnectionPlus) + assert True is plus_conn.atomic_in_progress + assert isolation_level == plus_conn.isolation_level + assert False is plus_conn.in_transaction # not True?? + + # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? + assert isinstance(atomic_conn_1, ConnectionPlus) + assert True is atomic_conn_1.atomic_in_progress + assert isolation_level is atomic_conn_1.isolation_level + assert False is atomic_conn_1.in_transaction # not True?? with atomic(atomic_conn_1) as atomic_conn_2: - # assert plus_conn_in_transaction(plus_conn) <-- should it be? - assert plus_conn_is_idle(plus_conn, isolation_level) + # assert plus_conn_in_transaction(plus_conn) # <-- should it be? + assert isinstance(plus_conn, ConnectionPlus) + assert True is plus_conn.atomic_in_progress + assert isolation_level is plus_conn.isolation_level + assert False is plus_conn.in_transaction # not True?? + # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? - assert plus_conn_is_idle(atomic_conn_1, isolation_level) - # assert plus_conn_in_transaction(atomic_conn_2) <-- should it be? - assert plus_conn_is_idle(atomic_conn_2, isolation_level) + assert isinstance(atomic_conn_1, ConnectionPlus) + assert True is atomic_conn_1.atomic_in_progress + assert isolation_level == atomic_conn_1.isolation_level # not None?? + assert False is atomic_conn_1.in_transaction # not True??? + + # assert plus_conn_in_transaction(atomic_conn_2) # <-- should it be? + assert isinstance(atomic_conn_2, ConnectionPlus) + assert True is atomic_conn_2.atomic_in_progress + assert isolation_level == atomic_conn_2.isolation_level # not None?? + assert False is atomic_conn_2.in_transaction # not True??? # assert plus_conn_in_transaction(plus_conn) <-- should it be? - assert plus_conn_is_idle(plus_conn, isolation_level) + assert isinstance(plus_conn, ConnectionPlus) + assert True is plus_conn.atomic_in_progress + assert isolation_level == plus_conn.isolation_level # not None?? + assert False is plus_conn.in_transaction # not True? + # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? - assert plus_conn_is_idle(atomic_conn_1, isolation_level) + assert isinstance(atomic_conn_1, ConnectionPlus) + assert True is atomic_conn_1.atomic_in_progress + assert isolation_level == atomic_conn_1.isolation_level # not None?? + assert False is atomic_conn_1.in_transaction # not True? + # assert plus_conn_in_transaction(atomic_conn_2) <-- should it be? - assert plus_conn_is_idle(atomic_conn_2, isolation_level) + assert isinstance(atomic_conn_2, ConnectionPlus) + assert True is atomic_conn_2.atomic_in_progress + assert isolation_level == atomic_conn_2.isolation_level # not None?? + assert False is atomic_conn_2.in_transaction # not True? - assert plus_conn_is_idle(plus_conn, isolation_level) - assert plus_conn_is_idle(atomic_conn_1, isolation_level) - assert plus_conn_is_idle(atomic_conn_2, isolation_level) + # assert plus_conn_is_idle(plus_conn, isolation_level) <-- should it be? + assert isinstance(plus_conn, ConnectionPlus) + assert True is plus_conn.atomic_in_progress # not False?? + assert isolation_level == plus_conn.isolation_level + assert False is plus_conn.in_transaction + + # assert plus_conn_is_idle(atomic_conn_1, isolation_level) <-- should it be? + assert isinstance(atomic_conn_1, ConnectionPlus) + assert True is atomic_conn_1.atomic_in_progress # not False?? + assert isolation_level == atomic_conn_1.isolation_level + assert False is atomic_conn_1.in_transaction + + # assert plus_conn_is_idle(atomic_conn_2, isolation_level) <-- should it be? + assert isinstance(atomic_conn_2, ConnectionPlus) + assert True is atomic_conn_2.atomic_in_progress # not False?? + assert isolation_level == atomic_conn_2.isolation_level + assert False is atomic_conn_2.in_transaction assert atomic_in_progress == plus_conn.atomic_in_progress assert atomic_in_progress == atomic_conn_1.atomic_in_progress From 3cc06bd5a33677d2165a28a353fc9acec02391ed Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 16:30:11 +0100 Subject: [PATCH 169/719] Use dataset fixture in test_modify_result directly --- qcodes/tests/dataset/test_dataset_basic.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 8e27ddd7e30..8300141d5a6 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -359,9 +359,7 @@ def test_modify_results(dataset): 'implemented and covered with tests.') -@pytest.mark.usefixtures("experiment") -def test_modify_result(): - dataset = new_data_set("test_modify_result") +def test_modify_result(dataset): xparam = ParamSpec("x", "numeric", label="x parameter", unit='V') yparam = ParamSpec("y", 'numeric', label='y parameter', From 71e6554aba74393b6458a3c5672e5ac1962ec489 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 16:31:44 +0100 Subject: [PATCH 170/719] Add failing test for ConnectionPlus that showcases a bug ConnectionPlus created via constructor does not commit in atomic context manager. --- .../tests/dataset/test_sqlite_connection.py | 108 +++++++++++++++++- 1 file changed, 102 insertions(+), 6 deletions(-) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 5b66ad5661e..fea27c63681 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -3,7 +3,7 @@ import pytest from qcodes.dataset.sqlite_base import ConnectionPlus, \ - make_plus_connection_from, atomic + make_plus_connection_from, atomic, connect def sqlite_conn_in_transaction(conn: sqlite3.Connection): @@ -36,7 +36,8 @@ def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): return True -@pytest.mark.xfail('this test showcases a weird behavior of `ConnectionPlus`') +@pytest.mark.xfail(reason='this test showcases a weird behavior of ' + '`ConnectionPlus`') def test_connection_plus(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -81,8 +82,8 @@ def test_atomic_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn, isolation_level) -@pytest.mark.xfail('this test showcases a weird behavior of `atomic`, ' - 'needs fixes, apparently also for `ConnectionPlus`') +@pytest.mark.xfail(reason='this test showcases a weird behavior of `atomic`, ' + 'needs fixes, apparently also for `ConnectionPlus`') def test_atomic_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -139,8 +140,8 @@ def test_two_atomics_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn_2, isolation_level) -@pytest.mark.xfail('this test showcases a weird behavior of `atomic`, ' - 'needs fixes, apparently also for `ConnectionPlus`') +@pytest.mark.xfail(reason='this test showcases a weird behavior of `atomic`, ' + 'needs fixes, apparently also for `ConnectionPlus`') def test_two_atomics_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -220,3 +221,98 @@ def test_two_atomics_on_outmost_plus_connection(): assert atomic_in_progress == plus_conn.atomic_in_progress assert atomic_in_progress == atomic_conn_1.atomic_in_progress assert atomic_in_progress == atomic_conn_2.atomic_in_progress + + +@pytest.mark.parametrize(argnames='create_conn_plus', + argvalues=( + make_plus_connection_from, + pytest.param(ConnectionPlus, + marks=pytest.mark.xfail( + strict=True)) + ), + ids=( + 'make_plus_connection_from', + 'ConnectionPlus' + )) +def test_use_of_atomic_that_does_not_commit(tmp_path, create_conn_plus): + """ + This test tests the behavior of `ConnectionPlus` that is created from + `sqlite3.Connection` with respect to `atomic` context manager and commits. + """ + dbfile = str(tmp_path / 'temp.db') + + sqlite_conn = connect(dbfile) + plus_conn = create_conn_plus(sqlite_conn) + + # this connection is going to be used to test whether changes have been + # committed to the database file + control_conn = connect(dbfile) + + get_all_runs = 'SELECT * FROM runs' + insert_run_with_name = 'INSERT INTO runs (name) VALUES (?)' + + # assert that at the beginning of the test there are no runs in the + # table; we'll be adding new rows to the runs table below + + assert 0 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 0 == len(control_conn.execute(get_all_runs).fetchall()) + + # add 1 new row, and assert the state of the runs table at every step + # note that control_conn will only detect the change after the `atomic` + # context manager is exited + + with atomic(plus_conn) as atomic_conn: + + assert 0 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 0 == len(atomic_conn.execute(get_all_runs).fetchall()) + assert 0 == len(control_conn.execute(get_all_runs).fetchall()) + + atomic_conn.cursor().execute(insert_run_with_name, ['aaa']) + + assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(atomic_conn.execute(get_all_runs).fetchall()) + assert 0 == len(control_conn.execute(get_all_runs).fetchall()) + + assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(atomic_conn.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + # let's add two new rows but each inside its own `atomic` context manager + # we expect to see the actual change in the database only after we exit + # the outermost context. + + with atomic(plus_conn) as atomic_conn_1: + + assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + atomic_conn_1.cursor().execute(insert_run_with_name, ['bbb']) + + assert 2 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 2 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + with atomic(atomic_conn_1) as atomic_conn_2: + + assert 2 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 2 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 2 == len(atomic_conn_2.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + atomic_conn_2.cursor().execute(insert_run_with_name, ['ccc']) + + assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) + assert 1 == len(control_conn.execute(get_all_runs).fetchall()) + + assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) + assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) + assert 3 == len(control_conn.execute(get_all_runs).fetchall()) From bf7c17f0020c36b792713a614d37f507949b1ab2 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 20 Nov 2018 17:43:49 +0100 Subject: [PATCH 171/719] Fix atomic called on constructor-created ConnectionPlus doesnt commit (as opposed to on ConnectionPlus created by `make_plus_connection_from`) Setting initial atomic_in_progress to True fixes it. --- qcodes/dataset/sqlite_base.py | 3 +- .../tests/dataset/test_sqlite_connection.py | 157 +++++++----------- 2 files changed, 58 insertions(+), 102 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 3426cc2514f..bdc1475ccac 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -118,7 +118,7 @@ class ConnectionPlus(wrapt.ObjectProxy): currently in the middle of an atomic block of transactions, thus allowing us to nest atomic context managers """ - atomic_in_progress: bool = True + atomic_in_progress: bool = False SomeConnection = Union[sqlite3.Connection, ConnectionPlus] @@ -789,7 +789,6 @@ def make_plus_connection_from(conn: SomeConnection) -> ConnectionPlus: """ if not (hasattr(conn, 'atomic_in_progress')): conn = ConnectionPlus(conn) - conn.atomic_in_progress = False else: conn = cast(ConnectionPlus, conn) return conn diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index fea27c63681..3a6bec31a56 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -36,17 +36,13 @@ def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): return True -@pytest.mark.xfail(reason='this test showcases a weird behavior of ' - '`ConnectionPlus`') def test_connection_plus(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) assert isinstance(plus_conn, ConnectionPlus) assert isinstance(plus_conn, sqlite3.Connection) - # reason for the value of "True" here is unknown - assert True is plus_conn.atomic_in_progress - # assert False is plus_conn.atomic_in_progress <-- should it be? + assert False is plus_conn.atomic_in_progress @pytest.mark.parametrize( @@ -61,11 +57,8 @@ def test_make_plus_connection_from(conn): assert isinstance(plus_conn, ConnectionPlus) if isinstance(conn, ConnectionPlus): - # make_plus_connection_from does not change this, hence it should be - # equal to the value from `conn` (which is True, see ConnectionPlus) assert conn.atomic_in_progress is plus_conn.atomic_in_progress else: - # make_plus_connection_from explicitly sets this to False assert False is plus_conn.atomic_in_progress @@ -82,38 +75,61 @@ def test_atomic_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn, isolation_level) -@pytest.mark.xfail(reason='this test showcases a weird behavior of `atomic`, ' - 'needs fixes, apparently also for `ConnectionPlus`') def test_atomic_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) + assert False is plus_conn.atomic_in_progress atomic_in_progress = plus_conn.atomic_in_progress - isolation_level = plus_conn.isolation_level + assert False is plus_conn.in_transaction with atomic(plus_conn) as atomic_conn: - assert isinstance(atomic_conn, ConnectionPlus) + assert plus_conn_in_transaction(atomic_conn) + assert plus_conn_in_transaction(plus_conn) - assert True is atomic_conn.atomic_in_progress + assert isolation_level == plus_conn.isolation_level + assert False is plus_conn.in_transaction + assert atomic_in_progress is plus_conn.atomic_in_progress - # assert None is atomic_conn.isolation_level <-- should it be? - assert isolation_level == atomic_conn.isolation_level - # assert None is plus_conn.isolation_level <-- should it be? + assert isolation_level == plus_conn.isolation_level + assert False is atomic_conn.in_transaction + assert atomic_in_progress is atomic_conn.atomic_in_progress + + +@pytest.mark.parametrize('in_transaction', (True, False)) +def test_atomic_on_outmost_plus_connection_that_is_in_progress(in_transaction): + sqlite_conn = sqlite3.connect(':memory:') + plus_conn = ConnectionPlus(sqlite_conn) + + # explicitly set to True for testing purposes + plus_conn.atomic_in_progress = True + + # implement parametrizing over connection's `in_transaction` attribute + if in_transaction: + plus_conn.cursor().execute('BEGIN') + assert in_transaction is plus_conn.in_transaction + + isolation_level = plus_conn.isolation_level + in_transaction = plus_conn.in_transaction + + with atomic(plus_conn) as atomic_conn: + assert True is plus_conn.atomic_in_progress assert isolation_level == plus_conn.isolation_level + assert in_transaction is plus_conn.in_transaction - # assert True is plus_conn.in_transaction <-- should it be? - assert False is plus_conn.in_transaction - # assert True is atomic_conn.in_transaction <-- should it be? - assert False is atomic_conn.in_transaction + assert True is atomic_conn.atomic_in_progress + assert isolation_level == atomic_conn.isolation_level + assert in_transaction is atomic_conn.in_transaction + assert True is plus_conn.atomic_in_progress assert isolation_level == plus_conn.isolation_level - assert False is plus_conn.in_transaction + assert in_transaction is plus_conn.in_transaction - assert False is atomic_conn.in_transaction - - assert atomic_in_progress is atomic_conn.atomic_in_progress + assert True is atomic_conn.atomic_in_progress + assert isolation_level == atomic_conn.isolation_level + assert in_transaction is atomic_conn.in_transaction def test_two_atomics_on_outmost_sqlite_connection(): @@ -140,83 +156,31 @@ def test_two_atomics_on_outmost_sqlite_connection(): assert plus_conn_is_idle(atomic_conn_2, isolation_level) -@pytest.mark.xfail(reason='this test showcases a weird behavior of `atomic`, ' - 'needs fixes, apparently also for `ConnectionPlus`') def test_two_atomics_on_outmost_plus_connection(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) - atomic_in_progress = plus_conn.atomic_in_progress + atomic_in_progress = plus_conn.atomic_in_progress isolation_level = plus_conn.isolation_level + assert False is plus_conn.in_transaction with atomic(plus_conn) as atomic_conn_1: - # assert plus_conn_in_transaction(plus_conn) <-- should it be? - assert isinstance(plus_conn, ConnectionPlus) - assert True is plus_conn.atomic_in_progress - assert isolation_level == plus_conn.isolation_level - assert False is plus_conn.in_transaction # not True?? - - # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? - assert isinstance(atomic_conn_1, ConnectionPlus) - assert True is atomic_conn_1.atomic_in_progress - assert isolation_level is atomic_conn_1.isolation_level - assert False is atomic_conn_1.in_transaction # not True?? + assert plus_conn_in_transaction(plus_conn) + assert plus_conn_in_transaction(atomic_conn_1) with atomic(atomic_conn_1) as atomic_conn_2: - # assert plus_conn_in_transaction(plus_conn) # <-- should it be? - assert isinstance(plus_conn, ConnectionPlus) - assert True is plus_conn.atomic_in_progress - assert isolation_level is plus_conn.isolation_level - assert False is plus_conn.in_transaction # not True?? - - # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? - assert isinstance(atomic_conn_1, ConnectionPlus) - assert True is atomic_conn_1.atomic_in_progress - assert isolation_level == atomic_conn_1.isolation_level # not None?? - assert False is atomic_conn_1.in_transaction # not True??? - - # assert plus_conn_in_transaction(atomic_conn_2) # <-- should it be? - assert isinstance(atomic_conn_2, ConnectionPlus) - assert True is atomic_conn_2.atomic_in_progress - assert isolation_level == atomic_conn_2.isolation_level # not None?? - assert False is atomic_conn_2.in_transaction # not True??? - - # assert plus_conn_in_transaction(plus_conn) <-- should it be? - assert isinstance(plus_conn, ConnectionPlus) - assert True is plus_conn.atomic_in_progress - assert isolation_level == plus_conn.isolation_level # not None?? - assert False is plus_conn.in_transaction # not True? - - # assert plus_conn_in_transaction(atomic_conn_1) <-- should it be? - assert isinstance(atomic_conn_1, ConnectionPlus) - assert True is atomic_conn_1.atomic_in_progress - assert isolation_level == atomic_conn_1.isolation_level # not None?? - assert False is atomic_conn_1.in_transaction # not True? - - # assert plus_conn_in_transaction(atomic_conn_2) <-- should it be? - assert isinstance(atomic_conn_2, ConnectionPlus) - assert True is atomic_conn_2.atomic_in_progress - assert isolation_level == atomic_conn_2.isolation_level # not None?? - assert False is atomic_conn_2.in_transaction # not True? - - # assert plus_conn_is_idle(plus_conn, isolation_level) <-- should it be? - assert isinstance(plus_conn, ConnectionPlus) - assert True is plus_conn.atomic_in_progress # not False?? - assert isolation_level == plus_conn.isolation_level - assert False is plus_conn.in_transaction + assert plus_conn_in_transaction(plus_conn) + assert plus_conn_in_transaction(atomic_conn_1) + assert plus_conn_in_transaction(atomic_conn_2) - # assert plus_conn_is_idle(atomic_conn_1, isolation_level) <-- should it be? - assert isinstance(atomic_conn_1, ConnectionPlus) - assert True is atomic_conn_1.atomic_in_progress # not False?? - assert isolation_level == atomic_conn_1.isolation_level - assert False is atomic_conn_1.in_transaction + assert plus_conn_in_transaction(plus_conn) + assert plus_conn_in_transaction(atomic_conn_1) + assert plus_conn_in_transaction(atomic_conn_2) - # assert plus_conn_is_idle(atomic_conn_2, isolation_level) <-- should it be? - assert isinstance(atomic_conn_2, ConnectionPlus) - assert True is atomic_conn_2.atomic_in_progress # not False?? - assert isolation_level == atomic_conn_2.isolation_level - assert False is atomic_conn_2.in_transaction + assert plus_conn_is_idle(plus_conn, isolation_level) + assert plus_conn_is_idle(atomic_conn_1, isolation_level) + assert plus_conn_is_idle(atomic_conn_2, isolation_level) assert atomic_in_progress == plus_conn.atomic_in_progress assert atomic_in_progress == atomic_conn_1.atomic_in_progress @@ -224,17 +188,10 @@ def test_two_atomics_on_outmost_plus_connection(): @pytest.mark.parametrize(argnames='create_conn_plus', - argvalues=( - make_plus_connection_from, - pytest.param(ConnectionPlus, - marks=pytest.mark.xfail( - strict=True)) - ), - ids=( - 'make_plus_connection_from', - 'ConnectionPlus' - )) -def test_use_of_atomic_that_does_not_commit(tmp_path, create_conn_plus): + argvalues=(make_plus_connection_from, ConnectionPlus), + ids=('make_plus_connection_from', 'ConnectionPlus')) +def test_that_use_of_atomic_commits_only_at_outermost_context( + tmp_path, create_conn_plus): """ This test tests the behavior of `ConnectionPlus` that is created from `sqlite3.Connection` with respect to `atomic` context manager and commits. From b9e326636001ba8e3e5d585843cda54aebef6b9e Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 20 Nov 2018 17:07:45 -0800 Subject: [PATCH 172/719] initial commit --- .../Qcodes example with Stahl.ipynb | 309 ++++++++++++++++-- .../Spectrum/stahl/__init__.py | 0 .../Spectrum/stahl/stahl.py | 173 ++++++++++ 3 files changed, 460 insertions(+), 22 deletions(-) create mode 100644 qcodes/instrument_drivers/Spectrum/stahl/__init__.py create mode 100644 qcodes/instrument_drivers/Spectrum/stahl/stahl.py diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 8d079ed6513..ae1284076f2 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -6,76 +6,341 @@ "metadata": {}, "outputs": [], "source": [ - "from qcodes import VisaInstrument " + "from typing import Dict, Optional, List, Tuple, Callable\n", + "import re \n", + "import numpy as np \n", + "import logging\n", + "\n", + "from qcodes import VisaInstrument, InstrumentChannel, ChannelList\n", + "from qcodes.instrument.parameter import Parameter\n", + "from qcodes.utils.validators import Numbers" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "#stahl = VisaInstrument(\"stahl\", \"COM3\")" + "logger = logging.getLogger()\n", + "logger.setLevel(logging.DEBUG)" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "import visa\n", - "rm = visa.ResourceManager(visa_library=r\"C:\\Windows\\SysWOW64\\visa32.dll\")" + "class StahlChannel(InstrumentChannel): \n", + " def __init__(self, parent, name, channel_number): \n", + " super().__init__(parent, name)\n", + " \n", + " self._channel_string = f\"{channel_number:02d}\"\n", + " self._channel_number = channel_number\n", + " self._acknowledge_reply = chr(6)\n", + " \n", + " self.add_parameter(\n", + " \"voltage\", \n", + " get_cmd=f\"{self.parent.identifier} U{self._channel_string}\", \n", + " get_parser=self._stahl_get_parser(\"V\"), \n", + " set_cmd=self._set_voltage, \n", + " unit=\"V\",\n", + " vals=Numbers(\n", + " -self.parent.voltage_range, \n", + " self.parent.voltage_range\n", + " )\n", + " )\n", + " \n", + " self.add_parameter(\n", + " \"current\", \n", + " get_cmd=f\"{self.parent.identifier} I{self._channel_string}\", \n", + " get_parser=self._stahl_get_parser(\"mA\"), \n", + " unit=\"mA\",\n", + " )\n", + " \n", + " self.add_parameter(\n", + " \"is_locked\", \n", + " get_cmd=self._get_lock_status, \n", + " get_parser={\"0\": False, \"1\": True}.get, \n", + " )\n", + " \n", + " def _stahl_get_parser(self, unit):\n", + " \n", + " regex = f\"([\\+\\-][\\d]?\\d,\\d{{3}} ){unit}$\"\n", + " \n", + " def parser(response):\n", + " result = re.search(regex, response).groups()[0]\n", + " return float(result.replace(\",\", \".\"))\n", + " \n", + " return parser\n", + " \n", + " def _set_voltage(self, voltage): \n", + " \n", + " voltage_normalized = np.interp(\n", + " voltage, \n", + " self.parent.voltage_range * np.array([-1, 1]), \n", + " [0, 1]\n", + " )\n", + " \n", + " send_string = f\"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}\"\n", + " response = self.ask(send_string) # This is not a bug. We are asking in a set \n", + " \n", + " if response != self._acknowledge_reply: \n", + " logger.warning(f\"Command {expected_reply} did not produce an acknowledge reply\")\n", + " \n", + " def _get_lock_status(self): \n", + " \n", + " send_string = f\"{self.parent.identifier} LOCK\"\n", + " \n", + " response = self.parent.visa_handle.query_binary_values(\n", + " send_string, \n", + " datatype='B',\n", + " header_fmt=\"empty\"\n", + " )\n", + " \n", + " chnr = self._channel_number - 1\n", + " channel_group = chnr // 4\n", + " lock_code_group = response[channel_group]\n", + " return format(lock_code_group, \"b\")[chnr % 4 + 1]" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "#rm.open_resource(\"COM3\")" + "class Stahl(VisaInstrument): \n", + " def __init__(self, name, address): \n", + " super().__init__(name, address, terminator=\"\\r\")\n", + " self.visa_handle.baud_rate = 115200\n", + " \n", + " instrument_info = self._parse_idn_string(\n", + " self.ask(\"IDN\")\n", + " )\n", + " \n", + " for key, value in instrument_info.items(): \n", + " setattr(self, key, value)\n", + " \n", + " channels = ChannelList(\n", + " self, \"channel\", StahlChannel, snapshotable=False\n", + " )\n", + " \n", + " for channel_number in range(1, self.n_channels + 1):\n", + " name = f\"channel{channel_number}\"\n", + " channel = StahlChannel(\n", + " self, \n", + " name, \n", + " channel_number\n", + " )\n", + " self.add_submodule(name, channel)\n", + " channels.append(channel)\n", + " \n", + " self.add_submodule(\"channel\", channels)\n", + " \n", + " self.add_parameter(\n", + " \"temperature\", \n", + " get_cmd=self._get_temperature, \n", + " unit=\"C\"\n", + " )\n", + " \n", + " self.connect_message()\n", + " \n", + " def _get_temperature(self):\n", + " \n", + " send_string = f\"{self.identifier} TEMP\"\n", + " response_characters = self.visa_handle.query_binary_values(\n", + " send_string, \n", + " datatype='B', \n", + " header_fmt=\"empty\"\n", + " )\n", + " \n", + " response_string = \"\".join(map(chr, response_characters))\n", + " # The '°' is the reason why we cannot simply call 'ask'\n", + " # Stupid instrument :-(\n", + " groups = re.search(\"TEMP (.*)°C\", response_string).groups()\n", + " return float(groups[0])\n", + " \n", + " @staticmethod\n", + " def _parse_idn_string(ind_string): \n", + " \n", + " groups = re.search(\n", + " \"(HV|BS)(\\d{3}) (\\d{3}) (\\d{2}) [buqsm]\", \n", + " ind_string\n", + " ).groups()\n", + " \n", + " idparsers = {\n", + " \"model\": str, \n", + " \"serial_number\": str, \n", + " \"voltage_range\": float, \n", + " \"n_channels\": int, \n", + " \"output_type\": {\n", + " \"b\": \"bipolar\", \n", + " \"u\": \"unipolar\", \n", + " \"q\": \"quadrupole\", \n", + " \"s\": \"steerer\", \n", + " \"m\": \"bipolar milivolt\"\n", + " }.get\n", + " }\n", + " \n", + " return {\n", + " name: idparsers[name](value) \n", + " for name, value in zip(idparsers.keys(), groups)\n", + " }\n", + " \n", + " def get_idn(self) -> Dict[str, Optional[str]]:\n", + " \n", + " return {\n", + " \"vendor\": \"Stahl\", \n", + " \"model\": self.model, \n", + " \"serial\": self.serial_number, \n", + " \"firmware\": None\n", + " }\n", + " \n", + " @property \n", + " def identifier(self): \n", + " return f\"{self.model}{self.serial_number}\"" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 5, "metadata": {}, "outputs": [ { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'Serial'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0mSerial\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'Serial'" + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: Stahl HV (serial:171, firmware:None) in 0.07s\n" ] } ], "source": [ - "import Serial " + "stahl = Stahl(\"stahl\", \"ASRL3\")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.101\n" + ] + } + ], + "source": [ + "v = stahl.channel[0].voltage()\n", + "print(v)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.001\n" + ] + } + ], + "source": [ + "v = stahl.channel[4].voltage()\n", + "print(v)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-0.001\n" + ] + } + ], + "source": [ + "v = stahl.channel[9].voltage()\n", + "print(v)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "stahl.channel[0].voltage(0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.002" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stahl.channel[0].current()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "25.3" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stahl.temperature()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "()" + "False" ] }, - "execution_count": 2, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "rm.list_resources()" + "stahl.channel[1].is_locked()" ] }, { diff --git a/qcodes/instrument_drivers/Spectrum/stahl/__init__.py b/qcodes/instrument_drivers/Spectrum/stahl/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/qcodes/instrument_drivers/Spectrum/stahl/stahl.py b/qcodes/instrument_drivers/Spectrum/stahl/stahl.py new file mode 100644 index 00000000000..90bd4fd3c7d --- /dev/null +++ b/qcodes/instrument_drivers/Spectrum/stahl/stahl.py @@ -0,0 +1,173 @@ +from typing import Dict, Optional, Any, Callable +import re +import numpy as np +import logging + +from qcodes import VisaInstrument, InstrumentChannel, ChannelList +from qcodes.utils.validators import Numbers + + +logger = logging.getLogger() + + +class StahlChannel(InstrumentChannel): + def __init__(self, parent: VisaInstrument, name: str, channel_number: int): + super().__init__(parent, name) + + self._channel_string = f"{channel_number:02d}" + self._channel_number = channel_number + self._acknowledge_reply = chr(6) + + self.add_parameter( + "voltage", + get_cmd=f"{self.parent.identifier} U{self._channel_string}", + get_parser=self._stahl_get_parser("V"), + set_cmd=self._set_voltage, + unit="V", + vals=Numbers( + -self.parent.voltage_range, + self.parent.voltage_range + ) + ) + + self.add_parameter( + "current", + get_cmd=f"{self.parent.identifier} I{self._channel_string}", + get_parser=self._stahl_get_parser("mA"), + unit="mA", + ) + + self.add_parameter( + "is_locked", + get_cmd=self._get_lock_status, + get_parser={"0": False, "1": True}.get, + ) + + @staticmethod + def _stahl_get_parser(unit: str) -> Callable: + regex = f"([\+\-][\d]?\d,\d{{3}} ){unit}$" + + def parser(response): + result = re.search(regex, response).groups()[0] + return float(result.replace(",", ".")) + + return parser + + def _set_voltage(self, voltage: float) -> None: + voltage_normalized = np.interp( + voltage, + self.parent.voltage_range * np.array([-1, 1]), + [0, 1] + ) + + send_string = f"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}" + response = self.ask(send_string) # This is not a bug. We are asking in a set + + if response != self._acknowledge_reply: + logger.warning(f"Command {send_string} did not produce an acknowledge reply") + + def _get_lock_status(self) -> chr: + send_string = f"{self.parent.identifier} LOCK" + + response = self.parent.visa_handle.query_binary_values( + send_string, + datatype='B', + header_fmt="empty" + ) + + chnr = self._channel_number - 1 + channel_group = chnr // 4 + lock_code_group = response[channel_group] + return format(lock_code_group, "b")[chnr % 4 + 1] + + +class Stahl(VisaInstrument): + def __init__(self, name: str, address: str): + super().__init__(name, address, terminator="\r") + self.visa_handle.baud_rate = 115200 + + instrument_info = self._parse_idn_string( + self.ask("IDN") + ) + + for key, value in instrument_info.items(): + setattr(self, key, value) + + channels = ChannelList( + self, "channel", StahlChannel, snapshotable=False + ) + + for channel_number in range(1, self.n_channels + 1): + name = f"channel{channel_number}" + channel = StahlChannel( + self, + name, + channel_number + ) + self.add_submodule(name, channel) + channels.append(channel) + + self.add_submodule("channel", channels) + + self.add_parameter( + "temperature", + get_cmd=self._get_temperature, + unit="C" + ) + + self.connect_message() + + def _get_temperature(self) -> float: + + send_string = f"{self.identifier} TEMP" + response_characters = self.visa_handle.query_binary_values( + send_string, + datatype='B', + header_fmt="empty" + ) + + response_string = "".join(map(chr, response_characters)) + # The '°' is the reason why we cannot simply call 'ask' + # Stupid instrument :-( + groups = re.search("TEMP (.*)°C", response_string).groups() + return float(groups[0]) + + @staticmethod + def _parse_idn_string(ind_string) -> Dict[str, Any]: + + groups = re.search( + "(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]", + ind_string + ).groups() + + idparsers = { + "model": str, + "serial_number": str, + "voltage_range": float, + "n_channels": int, + "output_type": { + "b": "bipolar", + "u": "unipolar", + "q": "quadrupole", + "s": "steerer", + "m": "bipolar milivolt" + }.get + } + + return { + name: idparsers[name](value) + for name, value in zip(idparsers.keys(), groups) + } + + def get_idn(self) -> Dict[str, Optional[str]]: + + return { + "vendor": "Stahl", + "model": self.model, + "serial": self.serial_number, + "firmware": None + } + + @property + def identifier(self): + return f"{self.model}{self.serial_number}" From ef7dabdb3a0cd76418dc2e1307781c3d74e2016a Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 20 Nov 2018 17:09:52 -0800 Subject: [PATCH 173/719] initial commit --- .../Qcodes example with Stahl.ipynb | 226 ++---------------- .../Spectrum/stahl/__init__.py | 0 qcodes/instrument_drivers/stahl/__init__.py | 1 + .../{Spectrum => }/stahl/stahl.py | 0 4 files changed, 17 insertions(+), 210 deletions(-) delete mode 100644 qcodes/instrument_drivers/Spectrum/stahl/__init__.py create mode 100644 qcodes/instrument_drivers/stahl/__init__.py rename qcodes/instrument_drivers/{Spectrum => }/stahl/stahl.py (100%) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index ae1284076f2..4e2a31d3904 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -6,213 +6,19 @@ "metadata": {}, "outputs": [], "source": [ - "from typing import Dict, Optional, List, Tuple, Callable\n", - "import re \n", - "import numpy as np \n", - "import logging\n", - "\n", - "from qcodes import VisaInstrument, InstrumentChannel, ChannelList\n", - "from qcodes.instrument.parameter import Parameter\n", - "from qcodes.utils.validators import Numbers" + "from qcodes.instrument_drivers.stahl import Stahl" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [], - "source": [ - "logger = logging.getLogger()\n", - "logger.setLevel(logging.DEBUG)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "class StahlChannel(InstrumentChannel): \n", - " def __init__(self, parent, name, channel_number): \n", - " super().__init__(parent, name)\n", - " \n", - " self._channel_string = f\"{channel_number:02d}\"\n", - " self._channel_number = channel_number\n", - " self._acknowledge_reply = chr(6)\n", - " \n", - " self.add_parameter(\n", - " \"voltage\", \n", - " get_cmd=f\"{self.parent.identifier} U{self._channel_string}\", \n", - " get_parser=self._stahl_get_parser(\"V\"), \n", - " set_cmd=self._set_voltage, \n", - " unit=\"V\",\n", - " vals=Numbers(\n", - " -self.parent.voltage_range, \n", - " self.parent.voltage_range\n", - " )\n", - " )\n", - " \n", - " self.add_parameter(\n", - " \"current\", \n", - " get_cmd=f\"{self.parent.identifier} I{self._channel_string}\", \n", - " get_parser=self._stahl_get_parser(\"mA\"), \n", - " unit=\"mA\",\n", - " )\n", - " \n", - " self.add_parameter(\n", - " \"is_locked\", \n", - " get_cmd=self._get_lock_status, \n", - " get_parser={\"0\": False, \"1\": True}.get, \n", - " )\n", - " \n", - " def _stahl_get_parser(self, unit):\n", - " \n", - " regex = f\"([\\+\\-][\\d]?\\d,\\d{{3}} ){unit}$\"\n", - " \n", - " def parser(response):\n", - " result = re.search(regex, response).groups()[0]\n", - " return float(result.replace(\",\", \".\"))\n", - " \n", - " return parser\n", - " \n", - " def _set_voltage(self, voltage): \n", - " \n", - " voltage_normalized = np.interp(\n", - " voltage, \n", - " self.parent.voltage_range * np.array([-1, 1]), \n", - " [0, 1]\n", - " )\n", - " \n", - " send_string = f\"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}\"\n", - " response = self.ask(send_string) # This is not a bug. We are asking in a set \n", - " \n", - " if response != self._acknowledge_reply: \n", - " logger.warning(f\"Command {expected_reply} did not produce an acknowledge reply\")\n", - " \n", - " def _get_lock_status(self): \n", - " \n", - " send_string = f\"{self.parent.identifier} LOCK\"\n", - " \n", - " response = self.parent.visa_handle.query_binary_values(\n", - " send_string, \n", - " datatype='B',\n", - " header_fmt=\"empty\"\n", - " )\n", - " \n", - " chnr = self._channel_number - 1\n", - " channel_group = chnr // 4\n", - " lock_code_group = response[channel_group]\n", - " return format(lock_code_group, \"b\")[chnr % 4 + 1]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "class Stahl(VisaInstrument): \n", - " def __init__(self, name, address): \n", - " super().__init__(name, address, terminator=\"\\r\")\n", - " self.visa_handle.baud_rate = 115200\n", - " \n", - " instrument_info = self._parse_idn_string(\n", - " self.ask(\"IDN\")\n", - " )\n", - " \n", - " for key, value in instrument_info.items(): \n", - " setattr(self, key, value)\n", - " \n", - " channels = ChannelList(\n", - " self, \"channel\", StahlChannel, snapshotable=False\n", - " )\n", - " \n", - " for channel_number in range(1, self.n_channels + 1):\n", - " name = f\"channel{channel_number}\"\n", - " channel = StahlChannel(\n", - " self, \n", - " name, \n", - " channel_number\n", - " )\n", - " self.add_submodule(name, channel)\n", - " channels.append(channel)\n", - " \n", - " self.add_submodule(\"channel\", channels)\n", - " \n", - " self.add_parameter(\n", - " \"temperature\", \n", - " get_cmd=self._get_temperature, \n", - " unit=\"C\"\n", - " )\n", - " \n", - " self.connect_message()\n", - " \n", - " def _get_temperature(self):\n", - " \n", - " send_string = f\"{self.identifier} TEMP\"\n", - " response_characters = self.visa_handle.query_binary_values(\n", - " send_string, \n", - " datatype='B', \n", - " header_fmt=\"empty\"\n", - " )\n", - " \n", - " response_string = \"\".join(map(chr, response_characters))\n", - " # The '°' is the reason why we cannot simply call 'ask'\n", - " # Stupid instrument :-(\n", - " groups = re.search(\"TEMP (.*)°C\", response_string).groups()\n", - " return float(groups[0])\n", - " \n", - " @staticmethod\n", - " def _parse_idn_string(ind_string): \n", - " \n", - " groups = re.search(\n", - " \"(HV|BS)(\\d{3}) (\\d{3}) (\\d{2}) [buqsm]\", \n", - " ind_string\n", - " ).groups()\n", - " \n", - " idparsers = {\n", - " \"model\": str, \n", - " \"serial_number\": str, \n", - " \"voltage_range\": float, \n", - " \"n_channels\": int, \n", - " \"output_type\": {\n", - " \"b\": \"bipolar\", \n", - " \"u\": \"unipolar\", \n", - " \"q\": \"quadrupole\", \n", - " \"s\": \"steerer\", \n", - " \"m\": \"bipolar milivolt\"\n", - " }.get\n", - " }\n", - " \n", - " return {\n", - " name: idparsers[name](value) \n", - " for name, value in zip(idparsers.keys(), groups)\n", - " }\n", - " \n", - " def get_idn(self) -> Dict[str, Optional[str]]:\n", - " \n", - " return {\n", - " \"vendor\": \"Stahl\", \n", - " \"model\": self.model, \n", - " \"serial\": self.serial_number, \n", - " \"firmware\": None\n", - " }\n", - " \n", - " @property \n", - " def identifier(self): \n", - " return f\"{self.model}{self.serial_number}\"" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Stahl HV (serial:171, firmware:None) in 0.07s\n" + "Connected to: Stahl HV (serial:171, firmware:None) in 0.20s\n" ] } ], @@ -222,14 +28,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "0.101\n" + "0.1\n" ] } ], @@ -240,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -258,14 +64,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "-0.001\n" + "-0.0\n" ] } ], @@ -276,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -285,16 +91,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0.002" + "0.001" ] }, - "execution_count": 10, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -305,16 +111,16 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "25.3" + "25.9" ] }, - "execution_count": 11, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -325,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -334,7 +140,7 @@ "False" ] }, - "execution_count": 12, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } diff --git a/qcodes/instrument_drivers/Spectrum/stahl/__init__.py b/qcodes/instrument_drivers/Spectrum/stahl/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/qcodes/instrument_drivers/stahl/__init__.py b/qcodes/instrument_drivers/stahl/__init__.py new file mode 100644 index 00000000000..3b522091e04 --- /dev/null +++ b/qcodes/instrument_drivers/stahl/__init__.py @@ -0,0 +1 @@ +from .stahl import Stahl diff --git a/qcodes/instrument_drivers/Spectrum/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py similarity index 100% rename from qcodes/instrument_drivers/Spectrum/stahl/stahl.py rename to qcodes/instrument_drivers/stahl/stahl.py From 79eb07f2a5a8f3661ff83afed689cf246d41afd4 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 21 Nov 2018 16:53:33 +0100 Subject: [PATCH 174/719] bugfix: allow empty traces --- qcodes/instrument_drivers/tektronix/AWG5014.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG5014.py b/qcodes/instrument_drivers/tektronix/AWG5014.py index 3b36f40cf2b..7a194a252f1 100644 --- a/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -1145,12 +1145,13 @@ def make_send_and_load_awg_file_from_forged_sequence( else: for i in range(2): if len(marker_keys[i]) != 0: - n_samples = len(step_markers[marker_keys[i][0]]) + n_samples = len(step_markers[i][marker_keys[i][0]]) break if n_samples is None: raise RuntimeError('It is not allowed to upload an element ' 'without markers nor waveforms') blank_trace = np.zeros(n_samples) + # I think this does might add some traces dynamically if they are # not the same in all elements. Add check in the beginning step_waveforms_list = [step_waveforms.get(key, blank_trace) From 40289b81b01fde62c181c8ae740b84d3d63e59f5 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 21 Nov 2018 12:08:48 -0800 Subject: [PATCH 175/719] doc strings --- .../Qcodes example with Stahl.ipynb | 76 +++++++++++---- qcodes/instrument_drivers/stahl/stahl.py | 93 ++++++++++++++----- 2 files changed, 127 insertions(+), 42 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 4e2a31d3904..b7a5cd6ed8e 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Stahl HV (serial:171, firmware:None) in 0.20s\n" + "Connected to: Stahl HV (serial:171, firmware:None) in 0.07s\n" ] } ], @@ -35,7 +35,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "0.1\n" + "0.001\n" ] } ], @@ -48,12 +48,21 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, + "outputs": [], + "source": [ + "v = stahl.channel[4].voltage(-2)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "0.001\n" + "-1.997\n" ] } ], @@ -64,7 +73,16 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "v = stahl.channel[4].voltage(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -82,16 +100,7 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "stahl.channel[0].voltage(0.1)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -100,7 +109,7 @@ "0.001" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -111,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -120,7 +129,7 @@ "25.9" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -131,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -140,7 +149,7 @@ "False" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -149,6 +158,35 @@ "stahl.channel[1].is_locked()" ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "a = '+/-10,103 V'" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'+/-10.103'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.strip(\"V\").strip().replace(\",\", \".\")" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 90bd4fd3c7d..0e527ec72b0 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -1,3 +1,7 @@ +""" +This is a driver for the Stahl power supplies +""" + from typing import Dict, Optional, Any, Callable import re import numpy as np @@ -11,6 +15,14 @@ class StahlChannel(InstrumentChannel): + """ + A Stahl source channel + + Args: + parent + name + channel_number + """ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): super().__init__(parent, name) @@ -39,21 +51,37 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): self.add_parameter( "is_locked", - get_cmd=self._get_lock_status, - get_parser={"0": False, "1": True}.get, + get_cmd=self._get_lock_status ) @staticmethod def _stahl_get_parser(unit: str) -> Callable: - regex = f"([\+\-][\d]?\d,\d{{3}} ){unit}$" + """ + Upon querying the voltage and current, the response from the instrument + is `+/-yy,yyy V` or `+/-yy,yyy mA'. We strip the unit and replace the + comma with a dot. + + Args: + unit: The unit to strip - def parser(response): + Return: + parser: Parse a response to a float + """ + regex = f"([\+\-]\d+,\d{{3}} ){unit}$" + + def parser(response: str) -> float: result = re.search(regex, response).groups()[0] return float(result.replace(",", ".")) return parser def _set_voltage(self, voltage: float) -> None: + """ + Args: + voltage + """ + # Normalize the voltage in the range 0 to 1, where 0 is maximum negative + # voltage and 1 is maximum positive voltage voltage_normalized = np.interp( voltage, self.parent.voltage_range * np.array([-1, 1]), @@ -61,12 +89,18 @@ def _set_voltage(self, voltage: float) -> None: ) send_string = f"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}" - response = self.ask(send_string) # This is not a bug. We are asking in a set + response = self.ask(send_string) if response != self._acknowledge_reply: logger.warning(f"Command {send_string} did not produce an acknowledge reply") - def _get_lock_status(self) -> chr: + def _get_lock_status(self) -> bool: + """ + A lock occurs when an output is overloaded + + Return: + lock_status: True when locked + """ send_string = f"{self.parent.identifier} LOCK" response = self.parent.visa_handle.query_binary_values( @@ -78,10 +112,17 @@ def _get_lock_status(self) -> chr: chnr = self._channel_number - 1 channel_group = chnr // 4 lock_code_group = response[channel_group] - return format(lock_code_group, "b")[chnr % 4 + 1] + return format(lock_code_group, "b")[chnr % 4 + 1] == "1" class Stahl(VisaInstrument): + """ + Stahl driver. + + Args: + name + address: A serial port address + """ def __init__(self, name: str, address: str): super().__init__(name, address, terminator="\r") self.visa_handle.baud_rate = 115200 @@ -118,29 +159,32 @@ def __init__(self, name: str, address: str): self.connect_message() def _get_temperature(self) -> float: - + """ + When querying the temperature a non-ascii character to denote + the degree symbol '°' is present in the return string. For this + reason, we cannot use the `ask` method as it will attempt to + recode the response with utf-8, which will fail. We need to + manually set the decoding to latin-1 + """ send_string = f"{self.identifier} TEMP" - response_characters = self.visa_handle.query_binary_values( - send_string, - datatype='B', - header_fmt="empty" - ) - - response_string = "".join(map(chr, response_characters)) - # The '°' is the reason why we cannot simply call 'ask' - # Stupid instrument :-( - groups = re.search("TEMP (.*)°C", response_string).groups() + self.write(send_string) + response = self.visa_handle.read(encoding="latin-1") + groups = re.search("TEMP (.*)°C", response).groups() return float(groups[0]) @staticmethod def _parse_idn_string(ind_string) -> Dict[str, Any]: - + """ + Return: + dict with keys: "model", "serial_number", "voltage_range", + "n_channels", "output_type" + """ groups = re.search( "(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]", ind_string ).groups() - idparsers = { + id_parsers = { "model": str, "serial_number": str, "voltage_range": float, @@ -155,12 +199,15 @@ def _parse_idn_string(ind_string) -> Dict[str, Any]: } return { - name: idparsers[name](value) - for name, value in zip(idparsers.keys(), groups) + name: id_parsers[name](value) + for name, value in zip(id_parsers.keys(), groups) } def get_idn(self) -> Dict[str, Optional[str]]: - + """ + The Stahl sends a uncommon IDN string which does not include a + firmware version. + """ return { "vendor": "Stahl", "model": self.model, From 1cfeb4145e8d6a9bce1e3d9db20985b7b0e1b56e Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 21 Nov 2018 12:20:05 -0800 Subject: [PATCH 176/719] mypy needs type hint for id_parsers --- qcodes/instrument_drivers/stahl/stahl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 0e527ec72b0..4f5e826f8fb 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -184,7 +184,7 @@ def _parse_idn_string(ind_string) -> Dict[str, Any]: ind_string ).groups() - id_parsers = { + id_parsers: Dict[str, Callable] = { "model": str, "serial_number": str, "voltage_range": float, From 2bdd2a48a8f4d187be044edfc0e462707073fa48 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 21 Nov 2018 12:25:26 -0800 Subject: [PATCH 177/719] example notebook --- .../Qcodes example with Stahl.ipynb | 85 ++++++------------- 1 file changed, 25 insertions(+), 60 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index b7a5cd6ed8e..f4a21ccf526 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -1,5 +1,14 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction \n", + "\n", + "Example notebook how to set voltages with the Stahl bias sources" + ] + }, { "cell_type": "code", "execution_count": 1, @@ -35,12 +44,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "0.001\n" + "2.001\n" ] } ], "source": [ - "v = stahl.channel[0].voltage()\n", + "v = stahl.channel[4].voltage(2)\n", + "v = stahl.channel[4].voltage()\n", "print(v)" ] }, @@ -48,15 +58,6 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], - "source": [ - "v = stahl.channel[4].voltage(-2)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, "outputs": [ { "name": "stdout", @@ -67,49 +68,42 @@ } ], "source": [ + "v = stahl.channel[4].voltage(-2)\n", "v = stahl.channel[4].voltage()\n", "print(v)" ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "v = stahl.channel[4].voltage(0)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "-0.0\n" + "0.001\n" ] } ], "source": [ - "v = stahl.channel[9].voltage()\n", + "v = stahl.channel[4].voltage(0)\n", + "v = stahl.channel[4].voltage()\n", "print(v)" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0.001" + "0.002" ] }, - "execution_count": 8, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -120,16 +114,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "25.9" + "26.3" ] }, - "execution_count": 9, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -140,7 +134,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -149,7 +143,7 @@ "False" ] }, - "execution_count": 10, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -158,35 +152,6 @@ "stahl.channel[1].is_locked()" ] }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "a = '+/-10,103 V'" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'+/-10.103'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a.strip(\"V\").strip().replace(\",\", \".\")" - ] - }, { "cell_type": "code", "execution_count": null, From 0f8a725ee2f4f85117bfc4f26cf81a292932881a Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 21 Nov 2018 15:12:03 -0800 Subject: [PATCH 178/719] unpack tuple with comma's --- qcodes/instrument_drivers/stahl/stahl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 4f5e826f8fb..45a672024ef 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -67,10 +67,10 @@ def _stahl_get_parser(unit: str) -> Callable: Return: parser: Parse a response to a float """ - regex = f"([\+\-]\d+,\d{{3}} ){unit}$" + regex = f"([\+\-]\d+,\d+ ){unit}$" def parser(response: str) -> float: - result = re.search(regex, response).groups()[0] + result, = re.search(regex, response).groups() return float(result.replace(",", ".")) return parser @@ -163,14 +163,14 @@ def _get_temperature(self) -> float: When querying the temperature a non-ascii character to denote the degree symbol '°' is present in the return string. For this reason, we cannot use the `ask` method as it will attempt to - recode the response with utf-8, which will fail. We need to + decode the response with utf-8, which will fail. We need to manually set the decoding to latin-1 """ send_string = f"{self.identifier} TEMP" self.write(send_string) response = self.visa_handle.read(encoding="latin-1") - groups = re.search("TEMP (.*)°C", response).groups() - return float(groups[0]) + temperature_string, = re.search("TEMP (.*)°C", response).groups() + return float(temperature_string) @staticmethod def _parse_idn_string(ind_string) -> Dict[str, Any]: From 2914303314b01423b407f93c4d3b254b019c974f Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 22 Nov 2018 13:03:40 +0100 Subject: [PATCH 179/719] Add metadata to runs to be extracted --- qcodes/tests/dataset/test_database_extract_runs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index a61f1995da1..ada869522f2 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -98,6 +98,9 @@ def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): for ps in some_paramspecs[1].values()} source_dataset.add_result(result) + source_dataset.add_metadata('goodness', 'fair') + source_dataset.add_metadata('test', True) + source_dataset.mark_complete() extract_runs_into_db(source_path, target_path, source_dataset.run_id) From 4a0feb74edbbc9a22f8691ce5ee40b795d027191 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 18:58:13 +0100 Subject: [PATCH 180/719] Dont allow creating ConnectionPlus from ConnectionPlus objects --- qcodes/dataset/sqlite_base.py | 9 +++++++++ qcodes/tests/dataset/test_sqlite_connection.py | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 516e598b0bf..e978149b051 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -120,6 +120,15 @@ class ConnectionPlus(wrapt.ObjectProxy): """ atomic_in_progress: bool = False + def __init__(self, sqlite3_connection: sqlite3.Connection): + super(ConnectionPlus, self).__init__(sqlite3_connection) + + if isinstance(sqlite3_connection, ConnectionPlus): + raise ValueError('Attempted to create `ConnectionPlus` from a ' + '`ConnectionPlus` object which is not allowed.') + + + SomeConnection = Union[sqlite3.Connection, ConnectionPlus] diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 3a6bec31a56..0f634c2f79e 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -1,3 +1,4 @@ +import re import sqlite3 import pytest @@ -44,6 +45,11 @@ def test_connection_plus(): assert isinstance(plus_conn, sqlite3.Connection) assert False is plus_conn.atomic_in_progress + match_str = re.escape('Attempted to create `ConnectionPlus` from a ' + '`ConnectionPlus` object which is not allowed.') + with pytest.raises(ValueError, match=match_str): + ConnectionPlus(plus_conn) + @pytest.mark.parametrize( argnames='conn', From 098989ab8c93fd226f5372d75926c67630b4feda Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 18:58:30 +0100 Subject: [PATCH 181/719] Improve docstring of ConnectionPlus --- qcodes/dataset/sqlite_base.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index e978149b051..1162d26c22c 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -110,13 +110,17 @@ class ConnectionPlus(wrapt.ObjectProxy): """ - A class to extend the sqlite3.Connection object with a single extra - attribute. Since sqlite3.Connection has no __dict__, we can not directly - add the attribute to a normal instance. + A class to extend the sqlite3.Connection object. Since sqlite3.Connection + has no __dict__, we can not directly add attributes to its instance + directly. - The extra attribute is a bool describing whether the connection is - currently in the middle of an atomic block of transactions, thus allowing - us to nest atomic context managers + It is not allowed to instantiate a new `ConnectionPlus` object from a + `ConnectionPlus` object. + + Attributes: + atomic_in_progress: a bool describing whether the connection is + currently in the middle of an atomic block of transactions, thus + allowing to nest `atomic` context managers """ atomic_in_progress: bool = False From ceb0e97bf300d7763f800c3dcd2f8e3e9d23413b Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 19:36:43 +0100 Subject: [PATCH 182/719] Now connect returns ConnectionPlus instead of sqlite3.Connection --- qcodes/dataset/sqlite_base.py | 17 +++++++++-------- qcodes/tests/dataset/test_sqlite_connection.py | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 1162d26c22c..2caf310abf6 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -132,8 +132,6 @@ def __init__(self, sqlite3_connection: sqlite3.Connection): '`ConnectionPlus` object which is not allowed.') - - SomeConnection = Union[sqlite3.Connection, ConnectionPlus] @@ -307,21 +305,21 @@ def many_many(curr: sqlite3.Cursor, *columns: str) -> List[List[Any]]: def connect(name: str, debug: bool = False, - version: int=-1) -> sqlite3.Connection: + version: int=-1) -> ConnectionPlus: """ Connect or create database. If debug the queries will be echoed back. This function takes care of registering the numpy/sqlite type converters that we need. - Args: name: name or path to the sqlite file debug: whether or not to turn on tracing - version: which version to create. We count from 0. -1 means 'latest' - Should always be left at -1 except when testing. + version: which version to create. We count from 0. -1 means 'latest'. + Should always be left at -1 except when testing. Returns: - conn: connection object to the database + conn: connection object to the database (note, it is + `ConnectionPlus`, not `sqlite3.Connection` """ # register numpy->binary(TEXT) adapter @@ -331,7 +329,10 @@ def connect(name: str, debug: bool = False, # register binary(TEXT) -> numpy converter # for some reasons mypy complains about this sqlite3.register_converter("array", _convert_array) - conn = sqlite3.connect(name, detect_types=sqlite3.PARSE_DECLTYPES) + + sqlite3_conn = sqlite3.connect(name, detect_types=sqlite3.PARSE_DECLTYPES) + conn = ConnectionPlus(sqlite3_conn) + # sqlite3 options conn.row_factory = sqlite3.Row diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 0f634c2f79e..6ecafe72501 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -203,8 +203,11 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( `sqlite3.Connection` with respect to `atomic` context manager and commits. """ dbfile = str(tmp_path / 'temp.db') + # just initialize the database file, connection objects needed for + # testing in this test function are created separately, see below + connect(dbfile) - sqlite_conn = connect(dbfile) + sqlite_conn = sqlite3.connect(dbfile) plus_conn = create_conn_plus(sqlite_conn) # this connection is going to be used to test whether changes have been @@ -279,3 +282,13 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) assert 3 == len(control_conn.execute(get_all_runs).fetchall()) + + +def test_connect(): + conn = connect(':memory:') + + assert isinstance(conn, sqlite3.Connection) + assert isinstance(conn, ConnectionPlus) + assert False is conn.atomic_in_progress + + assert sqlite3.Row is conn.row_factory From ef1dfe89fe549d211f0917f9af04ce2e8955264f Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 19:40:36 +0100 Subject: [PATCH 183/719] Test that connect changes user version (because it performs upgrades) --- .../dataset/test_database_creation_and_upgrading.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/qcodes/tests/dataset/test_database_creation_and_upgrading.py b/qcodes/tests/dataset/test_database_creation_and_upgrading.py index 71b77b06180..83b49fbc256 100644 --- a/qcodes/tests/dataset/test_database_creation_and_upgrading.py +++ b/qcodes/tests/dataset/test_database_creation_and_upgrading.py @@ -69,6 +69,19 @@ def location_and_station_set_to(location: int, work_station: int): cfg.save_to_home() +LATEST_VERSION = 3 +VERSIONS = tuple(range(LATEST_VERSION + 1)) +LATEST_VERSION_ARG = -1 + + +@pytest.mark.parametrize('ver', + VERSIONS + (LATEST_VERSION_ARG,)) +def test_connect_upgrades_user_version(ver): + expected_version = ver if ver != LATEST_VERSION_ARG else LATEST_VERSION + conn = connect(':memory:', version=ver) + assert expected_version == get_user_version(conn) + + @pytest.mark.usefixtures("empty_temp_db") def test_tables_exist(): for version in [-1, 0, 1]: From a79d160f7ad2ffdb0a3f503abde220b1aa5fc6b5 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 19:43:00 +0100 Subject: [PATCH 184/719] test_tables_exist is now parametrized for all database versions --- .../test_database_creation_and_upgrading.py | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/qcodes/tests/dataset/test_database_creation_and_upgrading.py b/qcodes/tests/dataset/test_database_creation_and_upgrading.py index 83b49fbc256..6f7b7804935 100644 --- a/qcodes/tests/dataset/test_database_creation_and_upgrading.py +++ b/qcodes/tests/dataset/test_database_creation_and_upgrading.py @@ -74,28 +74,26 @@ def location_and_station_set_to(location: int, work_station: int): LATEST_VERSION_ARG = -1 -@pytest.mark.parametrize('ver', - VERSIONS + (LATEST_VERSION_ARG,)) +@pytest.mark.parametrize('ver', VERSIONS + (LATEST_VERSION_ARG,)) def test_connect_upgrades_user_version(ver): expected_version = ver if ver != LATEST_VERSION_ARG else LATEST_VERSION conn = connect(':memory:', version=ver) assert expected_version == get_user_version(conn) -@pytest.mark.usefixtures("empty_temp_db") -def test_tables_exist(): - for version in [-1, 0, 1]: - conn = connect(qc.config["core"]["db_location"], - qc.config["core"]["db_debug"], - version=version) - cursor = conn.execute("select sql from sqlite_master" - " where type = 'table'") - expected_tables = ['experiments', 'runs', 'layouts', 'dependencies'] - rows = [row for row in cursor] - assert len(rows) == len(expected_tables) - for row, expected_table in zip(rows, expected_tables): - assert expected_table in row['sql'] - conn.close() +@pytest.mark.parametrize('version', VERSIONS + (LATEST_VERSION_ARG,)) +def test_tables_exist(empty_temp_db, version): + conn = connect(qc.config["core"]["db_location"], + qc.config["core"]["db_debug"], + version=version) + cursor = conn.execute("select sql from sqlite_master" + " where type = 'table'") + expected_tables = ['experiments', 'runs', 'layouts', 'dependencies'] + rows = [row for row in cursor] + assert len(rows) == len(expected_tables) + for row, expected_table in zip(rows, expected_tables): + assert expected_table in row['sql'] + conn.close() def test_initialise_database_at_for_nonexisting_db(): From 3a57fc79229ecd96f7087637b39d0860f8ace508 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 22 Nov 2018 19:49:10 +0100 Subject: [PATCH 185/719] Extract upgrade_actions and newest_version as constants Additionally, this allows to correctly parametrize tests. --- qcodes/dataset/sqlite_base.py | 16 +++++++++------- .../test_database_creation_and_upgrading.py | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2caf310abf6..2eae6275051 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -364,19 +364,16 @@ def perform_db_upgrade(conn: SomeConnection, version: int=-1) -> None: upgrade and be a NOOP if the current version is higher than their target. Args: + conn: object for connection to the database version: Which version to upgrade to. We count from 0. -1 means 'newest version' """ - - upgrade_actions = [perform_db_upgrade_0_to_1, perform_db_upgrade_1_to_2, - perform_db_upgrade_2_to_3] - newest_version = len(upgrade_actions) - version = newest_version if version == -1 else version + version = NEWEST_VERSION if version == -1 else version current_version = get_user_version(conn) - if current_version < newest_version: + if current_version < NEWEST_VERSION: log.info("Commencing database upgrade") - for action in upgrade_actions[:version]: + for action in UPGRADE_ACTIONS[:version]: action(conn) @@ -698,6 +695,11 @@ def perform_db_upgrade_2_to_3(conn: SomeConnection) -> None: log.debug(f"Upgrade in transition, run number {run_id}: OK") +UPGRADE_ACTIONS = [perform_db_upgrade_0_to_1, perform_db_upgrade_1_to_2, + perform_db_upgrade_2_to_3] +NEWEST_VERSION = len(UPGRADE_ACTIONS) + + def transaction(conn: SomeConnection, sql: str, *args: Any) -> sqlite3.Cursor: """Perform a transaction. diff --git a/qcodes/tests/dataset/test_database_creation_and_upgrading.py b/qcodes/tests/dataset/test_database_creation_and_upgrading.py index 6f7b7804935..1b651108b66 100644 --- a/qcodes/tests/dataset/test_database_creation_and_upgrading.py +++ b/qcodes/tests/dataset/test_database_creation_and_upgrading.py @@ -25,7 +25,8 @@ atomic_transaction, perform_db_upgrade_0_to_1, perform_db_upgrade_1_to_2, - perform_db_upgrade_2_to_3) + perform_db_upgrade_2_to_3, + NEWEST_VERSION) from qcodes.dataset.guids import parse_guid import qcodes.tests.dataset @@ -69,7 +70,7 @@ def location_and_station_set_to(location: int, work_station: int): cfg.save_to_home() -LATEST_VERSION = 3 +LATEST_VERSION = NEWEST_VERSION VERSIONS = tuple(range(LATEST_VERSION + 1)) LATEST_VERSION_ARG = -1 From b83404de1f3ac279f80c0fb2e5815fa542dd362e Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 01:06:40 +0100 Subject: [PATCH 186/719] Make atomic accept only ConnectionPlus --- qcodes/dataset/sqlite_base.py | 12 ++-- .../tests/dataset/test_sqlite_connection.py | 71 +++++++++---------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2eae6275051..2dfe564e415 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -741,13 +741,14 @@ def atomic_transaction(conn: SomeConnection, sqlite cursor """ - with atomic(conn) as conn: - c = transaction(conn, sql, *args) + plus_conn = make_plus_connection_from(conn) + with atomic(plus_conn) as atomic_conn: + c = transaction(atomic_conn, sql, *args) return c @contextmanager -def atomic(conn: SomeConnection): +def atomic(conn: ConnectionPlus): """ Guard a series of transactions as atomic. If one fails the transaction is rolled back and no more transactions @@ -759,8 +760,9 @@ def atomic(conn: SomeConnection): Args: - conn: connection to guard """ - - conn = make_plus_connection_from(conn) + if not isinstance(conn, ConnectionPlus): + raise ValueError('atomic context manager only accepts ConnectionPlus ' + 'database connection objects.') old_atomic_in_progress = conn.atomic_in_progress is_outmost = not(conn.atomic_in_progress) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 6ecafe72501..f2f0035a57d 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -4,7 +4,7 @@ import pytest from qcodes.dataset.sqlite_base import ConnectionPlus, \ - make_plus_connection_from, atomic, connect + make_plus_connection_from, atomic, connect, atomic_transaction def sqlite_conn_in_transaction(conn: sqlite3.Connection): @@ -68,21 +68,15 @@ def test_make_plus_connection_from(conn): assert False is plus_conn.atomic_in_progress -def test_atomic_on_outmost_sqlite_connection(): +def test_atomic(): sqlite_conn = sqlite3.connect(':memory:') - isolation_level = sqlite_conn.isolation_level - assert False is sqlite_conn.in_transaction - - with atomic(sqlite_conn) as atomic_conn: - assert sqlite_conn_in_transaction(sqlite_conn) - assert plus_conn_in_transaction(atomic_conn) - - assert sqlite_conn_is_idle(sqlite_conn, isolation_level) - assert plus_conn_is_idle(atomic_conn, isolation_level) + match_str = re.escape('atomic context manager only accepts ConnectionPlus ' + 'database connection objects.') + with pytest.raises(ValueError, match=match_str): + with atomic(sqlite_conn): # type: ignore + pass -def test_atomic_on_outmost_plus_connection(): - sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) assert False is plus_conn.atomic_in_progress @@ -105,7 +99,7 @@ def test_atomic_on_outmost_plus_connection(): @pytest.mark.parametrize('in_transaction', (True, False)) -def test_atomic_on_outmost_plus_connection_that_is_in_progress(in_transaction): +def test_atomic_on_plus_connection_that_is_in_progress(in_transaction): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -138,31 +132,7 @@ def test_atomic_on_outmost_plus_connection_that_is_in_progress(in_transaction): assert in_transaction is atomic_conn.in_transaction -def test_two_atomics_on_outmost_sqlite_connection(): - sqlite_conn = sqlite3.connect(':memory:') - - isolation_level = sqlite_conn.isolation_level - assert False is sqlite_conn.in_transaction - - with atomic(sqlite_conn) as atomic_conn_1: - assert sqlite_conn_in_transaction(sqlite_conn) - assert plus_conn_in_transaction(atomic_conn_1) - - with atomic(atomic_conn_1) as atomic_conn_2: - assert sqlite_conn_in_transaction(sqlite_conn) - assert plus_conn_in_transaction(atomic_conn_2) - assert plus_conn_in_transaction(atomic_conn_1) - - assert sqlite_conn_in_transaction(sqlite_conn) - assert plus_conn_in_transaction(atomic_conn_1) - assert plus_conn_in_transaction(atomic_conn_2) - - assert sqlite_conn_is_idle(sqlite_conn, isolation_level) - assert plus_conn_is_idle(atomic_conn_1, isolation_level) - assert plus_conn_is_idle(atomic_conn_2, isolation_level) - - -def test_two_atomics_on_outmost_plus_connection(): +def test_two_nested_atomics(): sqlite_conn = sqlite3.connect(':memory:') plus_conn = ConnectionPlus(sqlite_conn) @@ -284,6 +254,29 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( assert 3 == len(control_conn.execute(get_all_runs).fetchall()) +@pytest.mark.parametrize(argnames='create_connection', + argvalues=( + sqlite3.connect, + lambda x: ConnectionPlus(sqlite3.connect(x))), + ids=( + 'sqlite3.Connection', + 'ConnectionPlus')) +def test_atomic_transaction(create_connection, tmp_path): + """Test that atomic_transaction works for both types of connection""" + dbfile = str(tmp_path / 'temp.db') + + conn = create_connection(dbfile) + + ctrl_conn = sqlite3.connect(dbfile) + + sql_create_table = 'CREATE TABLE smth (name TEXT)' + sql_table_exists = 'SELECT sql FROM sqlite_master WHERE TYPE = "table"' + + atomic_transaction(conn, sql_create_table) + + assert sql_create_table in ctrl_conn.execute(sql_table_exists).fetchall()[0] + + def test_connect(): conn = connect(':memory:') From b92b0547ab54e5a5e3672ed40666470bedaadb7e Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 01:39:05 +0100 Subject: [PATCH 187/719] make_plus_connection_from is stricter when processing given connection --- qcodes/dataset/sqlite_base.py | 10 ++++---- .../tests/dataset/test_sqlite_connection.py | 23 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2dfe564e415..b7176d137d4 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -803,13 +803,13 @@ def make_plus_connection_from(conn: SomeConnection) -> ConnectionPlus: conn: an sqlite connection object as defined by SomeConnection type Returns: - the same connection as ConnectionPlus object + the "same" connection but as ConnectionPlus object """ - if not (hasattr(conn, 'atomic_in_progress')): - conn = ConnectionPlus(conn) + if not isinstance(conn, ConnectionPlus): + conn_plus = ConnectionPlus(conn) else: - conn = cast(ConnectionPlus, conn) - return conn + conn_plus = cast(ConnectionPlus, conn) + return conn_plus def init_db(conn: SomeConnection)->None: diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index f2f0035a57d..95336fde203 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -51,21 +51,22 @@ def test_connection_plus(): ConnectionPlus(plus_conn) -@pytest.mark.parametrize( - argnames='conn', - argvalues=(sqlite3.connect(':memory:'), - ConnectionPlus(sqlite3.connect(':memory:'))), - ids=('sqlite3.Connection', 'ConnectionPlus') -) -def test_make_plus_connection_from(conn): +def test_make_plus_connection_from_sqlite3_connection(): + conn = sqlite3.connect(':memory:') plus_conn = make_plus_connection_from(conn) assert isinstance(plus_conn, ConnectionPlus) + assert False is plus_conn.atomic_in_progress + assert plus_conn is not conn + - if isinstance(conn, ConnectionPlus): - assert conn.atomic_in_progress is plus_conn.atomic_in_progress - else: - assert False is plus_conn.atomic_in_progress +def test_make_plus_connection_from_connecton_plus(): + conn = ConnectionPlus(sqlite3.connect(':memory:')) + plus_conn = make_plus_connection_from(conn) + + assert isinstance(plus_conn, ConnectionPlus) + assert conn.atomic_in_progress is plus_conn.atomic_in_progress + assert plus_conn is conn def test_atomic(): From 485dc2aed332be4afcaa6f8747b399ff80265c3f Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 01:49:01 +0100 Subject: [PATCH 188/719] Rename all plus_conn to conn_plus to resemble ConnectionPlus --- qcodes/dataset/sqlite_base.py | 6 +- .../tests/dataset/test_sqlite_connection.py | 152 +++++++++--------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index b7176d137d4..5535ac17b74 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -741,8 +741,8 @@ def atomic_transaction(conn: SomeConnection, sqlite cursor """ - plus_conn = make_plus_connection_from(conn) - with atomic(plus_conn) as atomic_conn: + conn_plus = make_connection_plus_from(conn) + with atomic(conn_plus) as atomic_conn: c = transaction(atomic_conn, sql, *args) return c @@ -792,7 +792,7 @@ def atomic(conn: ConnectionPlus): conn.atomic_in_progress = old_atomic_in_progress -def make_plus_connection_from(conn: SomeConnection) -> ConnectionPlus: +def make_connection_plus_from(conn: SomeConnection) -> ConnectionPlus: """ Makes a ConnectionPlus connection object out of a given argument. diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 95336fde203..23c1fee665c 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -4,7 +4,7 @@ import pytest from qcodes.dataset.sqlite_base import ConnectionPlus, \ - make_plus_connection_from, atomic, connect, atomic_transaction + make_connection_plus_from, atomic, connect, atomic_transaction def sqlite_conn_in_transaction(conn: sqlite3.Connection): @@ -14,7 +14,7 @@ def sqlite_conn_in_transaction(conn: sqlite3.Connection): return True -def plus_conn_in_transaction(conn: ConnectionPlus): +def conn_plus_in_transaction(conn: ConnectionPlus): assert isinstance(conn, ConnectionPlus) assert True is conn.atomic_in_progress assert None is conn.isolation_level @@ -29,7 +29,7 @@ def sqlite_conn_is_idle(conn: sqlite3.Connection, isolation=None): return True -def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): +def conn_plus_is_idle(conn: ConnectionPlus, isolation=None): assert isinstance(conn, ConnectionPlus) assert False is conn.atomic_in_progress assert isolation == conn.isolation_level @@ -39,34 +39,34 @@ def plus_conn_is_idle(conn: ConnectionPlus, isolation=None): def test_connection_plus(): sqlite_conn = sqlite3.connect(':memory:') - plus_conn = ConnectionPlus(sqlite_conn) + conn_plus = ConnectionPlus(sqlite_conn) - assert isinstance(plus_conn, ConnectionPlus) - assert isinstance(plus_conn, sqlite3.Connection) - assert False is plus_conn.atomic_in_progress + assert isinstance(conn_plus, ConnectionPlus) + assert isinstance(conn_plus, sqlite3.Connection) + assert False is conn_plus.atomic_in_progress match_str = re.escape('Attempted to create `ConnectionPlus` from a ' '`ConnectionPlus` object which is not allowed.') with pytest.raises(ValueError, match=match_str): - ConnectionPlus(plus_conn) + ConnectionPlus(conn_plus) -def test_make_plus_connection_from_sqlite3_connection(): +def test_make_connection_plus_from_sqlite3_connection(): conn = sqlite3.connect(':memory:') - plus_conn = make_plus_connection_from(conn) + conn_plus = make_connection_plus_from(conn) - assert isinstance(plus_conn, ConnectionPlus) - assert False is plus_conn.atomic_in_progress - assert plus_conn is not conn + assert isinstance(conn_plus, ConnectionPlus) + assert False is conn_plus.atomic_in_progress + assert conn_plus is not conn -def test_make_plus_connection_from_connecton_plus(): +def test_make_connection_plus_from_connecton_plus(): conn = ConnectionPlus(sqlite3.connect(':memory:')) - plus_conn = make_plus_connection_from(conn) + conn_plus = make_connection_plus_from(conn) - assert isinstance(plus_conn, ConnectionPlus) - assert conn.atomic_in_progress is plus_conn.atomic_in_progress - assert plus_conn is conn + assert isinstance(conn_plus, ConnectionPlus) + assert conn.atomic_in_progress is conn_plus.atomic_in_progress + assert conn_plus is conn def test_atomic(): @@ -78,55 +78,55 @@ def test_atomic(): with atomic(sqlite_conn): # type: ignore pass - plus_conn = ConnectionPlus(sqlite_conn) - assert False is plus_conn.atomic_in_progress + conn_plus = ConnectionPlus(sqlite_conn) + assert False is conn_plus.atomic_in_progress - atomic_in_progress = plus_conn.atomic_in_progress - isolation_level = plus_conn.isolation_level + atomic_in_progress = conn_plus.atomic_in_progress + isolation_level = conn_plus.isolation_level - assert False is plus_conn.in_transaction + assert False is conn_plus.in_transaction - with atomic(plus_conn) as atomic_conn: - assert plus_conn_in_transaction(atomic_conn) - assert plus_conn_in_transaction(plus_conn) + with atomic(conn_plus) as atomic_conn: + assert conn_plus_in_transaction(atomic_conn) + assert conn_plus_in_transaction(conn_plus) - assert isolation_level == plus_conn.isolation_level - assert False is plus_conn.in_transaction - assert atomic_in_progress is plus_conn.atomic_in_progress + assert isolation_level == conn_plus.isolation_level + assert False is conn_plus.in_transaction + assert atomic_in_progress is conn_plus.atomic_in_progress - assert isolation_level == plus_conn.isolation_level + assert isolation_level == conn_plus.isolation_level assert False is atomic_conn.in_transaction assert atomic_in_progress is atomic_conn.atomic_in_progress @pytest.mark.parametrize('in_transaction', (True, False)) -def test_atomic_on_plus_connection_that_is_in_progress(in_transaction): +def test_atomic_on_connection_plus_that_is_in_progress(in_transaction): sqlite_conn = sqlite3.connect(':memory:') - plus_conn = ConnectionPlus(sqlite_conn) + conn_plus = ConnectionPlus(sqlite_conn) # explicitly set to True for testing purposes - plus_conn.atomic_in_progress = True + conn_plus.atomic_in_progress = True # implement parametrizing over connection's `in_transaction` attribute if in_transaction: - plus_conn.cursor().execute('BEGIN') - assert in_transaction is plus_conn.in_transaction + conn_plus.cursor().execute('BEGIN') + assert in_transaction is conn_plus.in_transaction - isolation_level = plus_conn.isolation_level - in_transaction = plus_conn.in_transaction + isolation_level = conn_plus.isolation_level + in_transaction = conn_plus.in_transaction - with atomic(plus_conn) as atomic_conn: - assert True is plus_conn.atomic_in_progress - assert isolation_level == plus_conn.isolation_level - assert in_transaction is plus_conn.in_transaction + with atomic(conn_plus) as atomic_conn: + assert True is conn_plus.atomic_in_progress + assert isolation_level == conn_plus.isolation_level + assert in_transaction is conn_plus.in_transaction assert True is atomic_conn.atomic_in_progress assert isolation_level == atomic_conn.isolation_level assert in_transaction is atomic_conn.in_transaction - assert True is plus_conn.atomic_in_progress - assert isolation_level == plus_conn.isolation_level - assert in_transaction is plus_conn.in_transaction + assert True is conn_plus.atomic_in_progress + assert isolation_level == conn_plus.isolation_level + assert in_transaction is conn_plus.in_transaction assert True is atomic_conn.atomic_in_progress assert isolation_level == atomic_conn.isolation_level @@ -135,38 +135,38 @@ def test_atomic_on_plus_connection_that_is_in_progress(in_transaction): def test_two_nested_atomics(): sqlite_conn = sqlite3.connect(':memory:') - plus_conn = ConnectionPlus(sqlite_conn) + conn_plus = ConnectionPlus(sqlite_conn) - atomic_in_progress = plus_conn.atomic_in_progress - isolation_level = plus_conn.isolation_level + atomic_in_progress = conn_plus.atomic_in_progress + isolation_level = conn_plus.isolation_level - assert False is plus_conn.in_transaction + assert False is conn_plus.in_transaction - with atomic(plus_conn) as atomic_conn_1: - assert plus_conn_in_transaction(plus_conn) - assert plus_conn_in_transaction(atomic_conn_1) + with atomic(conn_plus) as atomic_conn_1: + assert conn_plus_in_transaction(conn_plus) + assert conn_plus_in_transaction(atomic_conn_1) with atomic(atomic_conn_1) as atomic_conn_2: - assert plus_conn_in_transaction(plus_conn) - assert plus_conn_in_transaction(atomic_conn_1) - assert plus_conn_in_transaction(atomic_conn_2) + assert conn_plus_in_transaction(conn_plus) + assert conn_plus_in_transaction(atomic_conn_1) + assert conn_plus_in_transaction(atomic_conn_2) - assert plus_conn_in_transaction(plus_conn) - assert plus_conn_in_transaction(atomic_conn_1) - assert plus_conn_in_transaction(atomic_conn_2) + assert conn_plus_in_transaction(conn_plus) + assert conn_plus_in_transaction(atomic_conn_1) + assert conn_plus_in_transaction(atomic_conn_2) - assert plus_conn_is_idle(plus_conn, isolation_level) - assert plus_conn_is_idle(atomic_conn_1, isolation_level) - assert plus_conn_is_idle(atomic_conn_2, isolation_level) + assert conn_plus_is_idle(conn_plus, isolation_level) + assert conn_plus_is_idle(atomic_conn_1, isolation_level) + assert conn_plus_is_idle(atomic_conn_2, isolation_level) - assert atomic_in_progress == plus_conn.atomic_in_progress + assert atomic_in_progress == conn_plus.atomic_in_progress assert atomic_in_progress == atomic_conn_1.atomic_in_progress assert atomic_in_progress == atomic_conn_2.atomic_in_progress @pytest.mark.parametrize(argnames='create_conn_plus', - argvalues=(make_plus_connection_from, ConnectionPlus), - ids=('make_plus_connection_from', 'ConnectionPlus')) + argvalues=(make_connection_plus_from, ConnectionPlus), + ids=('make_connection_plus_from', 'ConnectionPlus')) def test_that_use_of_atomic_commits_only_at_outermost_context( tmp_path, create_conn_plus): """ @@ -179,7 +179,7 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( connect(dbfile) sqlite_conn = sqlite3.connect(dbfile) - plus_conn = create_conn_plus(sqlite_conn) + conn_plus = create_conn_plus(sqlite_conn) # this connection is going to be used to test whether changes have been # committed to the database file @@ -191,26 +191,26 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( # assert that at the beginning of the test there are no runs in the # table; we'll be adding new rows to the runs table below - assert 0 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 0 == len(conn_plus.execute(get_all_runs).fetchall()) assert 0 == len(control_conn.execute(get_all_runs).fetchall()) # add 1 new row, and assert the state of the runs table at every step # note that control_conn will only detect the change after the `atomic` # context manager is exited - with atomic(plus_conn) as atomic_conn: + with atomic(conn_plus) as atomic_conn: - assert 0 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 0 == len(conn_plus.execute(get_all_runs).fetchall()) assert 0 == len(atomic_conn.execute(get_all_runs).fetchall()) assert 0 == len(control_conn.execute(get_all_runs).fetchall()) atomic_conn.cursor().execute(insert_run_with_name, ['aaa']) - assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(conn_plus.execute(get_all_runs).fetchall()) assert 1 == len(atomic_conn.execute(get_all_runs).fetchall()) assert 0 == len(control_conn.execute(get_all_runs).fetchall()) - assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(conn_plus.execute(get_all_runs).fetchall()) assert 1 == len(atomic_conn.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) @@ -218,38 +218,38 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( # we expect to see the actual change in the database only after we exit # the outermost context. - with atomic(plus_conn) as atomic_conn_1: + with atomic(conn_plus) as atomic_conn_1: - assert 1 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 1 == len(conn_plus.execute(get_all_runs).fetchall()) assert 1 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) atomic_conn_1.cursor().execute(insert_run_with_name, ['bbb']) - assert 2 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 2 == len(conn_plus.execute(get_all_runs).fetchall()) assert 2 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) with atomic(atomic_conn_1) as atomic_conn_2: - assert 2 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 2 == len(conn_plus.execute(get_all_runs).fetchall()) assert 2 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 2 == len(atomic_conn_2.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) atomic_conn_2.cursor().execute(insert_run_with_name, ['ccc']) - assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(conn_plus.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) - assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(conn_plus.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) assert 1 == len(control_conn.execute(get_all_runs).fetchall()) - assert 3 == len(plus_conn.execute(get_all_runs).fetchall()) + assert 3 == len(conn_plus.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_1.execute(get_all_runs).fetchall()) assert 3 == len(atomic_conn_2.execute(get_all_runs).fetchall()) assert 3 == len(control_conn.execute(get_all_runs).fetchall()) From 0f63565744648911f9a9ed5d404475485134b3bc Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 01:55:47 +0100 Subject: [PATCH 189/719] Add explicit test for exception within atomic context manager --- .../tests/dataset/test_sqlite_connection.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 23c1fee665c..52815ad85d7 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -5,6 +5,8 @@ from qcodes.dataset.sqlite_base import ConnectionPlus, \ make_connection_plus_from, atomic, connect, atomic_transaction +from qcodes.tests.dataset.test_database_creation_and_upgrading import \ + error_caused_by def sqlite_conn_in_transaction(conn: sqlite3.Connection): @@ -99,6 +101,25 @@ def test_atomic(): assert atomic_in_progress is atomic_conn.atomic_in_progress +def test_atomic_with_exception(): + sqlite_conn = sqlite3.connect(':memory:') + conn_plus = ConnectionPlus(sqlite_conn) + + sqlite_conn.execute('PRAGMA user_version(25)') + sqlite_conn.commit() + + assert 25 == sqlite_conn.execute('PRAGMA user_version').fetchall()[0][0] + + with pytest.raises(RuntimeError, + match="Rolling back due to unhandled exception") as e: + with atomic(conn_plus) as atomic_conn: + atomic_conn.execute('PRAGMA user_version(42)') + raise Exception('intended exception') + assert error_caused_by(e, 'intended exception') + + assert 25 == sqlite_conn.execute('PRAGMA user_version').fetchall()[0][0] + + @pytest.mark.parametrize('in_transaction', (True, False)) def test_atomic_on_connection_plus_that_is_in_progress(in_transaction): sqlite_conn = sqlite3.connect(':memory:') From a5ae48d68eca522748a77ed48d8e32870cdf7985 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 02:04:55 +0100 Subject: [PATCH 190/719] Minor rearrangement of code of atomic --- qcodes/dataset/sqlite_base.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 5535ac17b74..c18c4a5d5fa 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -751,28 +751,31 @@ def atomic_transaction(conn: SomeConnection, def atomic(conn: ConnectionPlus): """ Guard a series of transactions as atomic. - If one fails the transaction is rolled back and no more transactions - are performed. + + If one transaction fails, all the previous transactions are rolled back + and no more transactions are performed. + NB: 'BEGIN' is by default only inserted before INSERT/UPDATE/DELETE/REPLACE but we want to guard any transaction that modifies the database (e.g. also ALTER) Args: - - conn: connection to guard + conn: connection to guard """ if not isinstance(conn, ConnectionPlus): raise ValueError('atomic context manager only accepts ConnectionPlus ' 'database connection objects.') - old_atomic_in_progress = conn.atomic_in_progress is_outmost = not(conn.atomic_in_progress) - conn.atomic_in_progress = True if conn.in_transaction and is_outmost: raise RuntimeError('SQLite connection has uncommited transactions. ' 'Please commit those before starting an atomic ' 'transaction.') + old_atomic_in_progress = conn.atomic_in_progress + conn.atomic_in_progress = True + try: if is_outmost: old_level = conn.isolation_level From 1fd54cdf1fdfcc9a04427a3ccc731f0d08bf300f Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 23 Nov 2018 02:05:24 +0100 Subject: [PATCH 191/719] Test atomic raises on outmost connection that is in transaction --- qcodes/dataset/sqlite_base.py | 2 +- qcodes/tests/dataset/test_sqlite_connection.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index c18c4a5d5fa..0f7a0d4fed8 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -769,7 +769,7 @@ def atomic(conn: ConnectionPlus): is_outmost = not(conn.atomic_in_progress) if conn.in_transaction and is_outmost: - raise RuntimeError('SQLite connection has uncommited transactions. ' + raise RuntimeError('SQLite connection has uncommitted transactions. ' 'Please commit those before starting an atomic ' 'transaction.') diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 52815ad85d7..31701481895 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -120,6 +120,20 @@ def test_atomic_with_exception(): assert 25 == sqlite_conn.execute('PRAGMA user_version').fetchall()[0][0] +def test_atomic_on_outmost_connection_that_is_in_transaction(): + conn = ConnectionPlus(sqlite3.connect(':memory:')) + + conn.execute('BEGIN') + assert True is conn.in_transaction + + match_str = re.escape('SQLite connection has uncommitted transactions. ' + 'Please commit those before starting an atomic ' + 'transaction.') + with pytest.raises(RuntimeError, match=match_str): + with atomic(conn): + pass + + @pytest.mark.parametrize('in_transaction', (True, False)) def test_atomic_on_connection_plus_that_is_in_progress(in_transaction): sqlite_conn = sqlite3.connect(':memory:') From 29bce594598d9f4176b5b240cf0d8805661eee4a Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 10:02:43 +0100 Subject: [PATCH 192/719] Use ConnectionPlus where it is needed instead of sqlite3.Connection also restrict the type of database upgrader functions. --- qcodes/dataset/sqlite_base.py | 47 ++++++++++--------- .../tests/dataset/test_sqlite_connection.py | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 0f7a0d4fed8..7c20af7f9e2 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -135,14 +135,15 @@ def __init__(self, sqlite3_connection: sqlite3.Connection): SomeConnection = Union[sqlite3.Connection, ConnectionPlus] -def upgrader(func: Callable[[SomeConnection], None]): +def upgrader(func: Callable[[ConnectionPlus], None]): """ Decorator for database version upgrade functions. An upgrade function - must have the name `perform_db_upgrade_N_to_M` where N = M-1. - The upgrade function must either perform the upgrade and return (no return - values allowed) or fail to perform the upgrade, in which case it must raise - a RuntimeError. A failed upgrade must be completely rolled back before the - RuntimeError is raises. + must have the name `perform_db_upgrade_N_to_M` where N = M-1. For + simplicity, an upgrade function must take a single argument of type + `ConnectionPlus`. The upgrade function must either perform the upgrade + and return (no return values allowed) or fail to perform the upgrade, + in which case it must raise a RuntimeError. A failed upgrade must be + completely rolled back before the RuntimeError is raises. The decorator takes care of logging about the upgrade and managing the database versioning. @@ -165,7 +166,7 @@ def upgrader(func: Callable[[SomeConnection], None]): ' to version N+1') @wraps(func) - def do_upgrade(conn: SomeConnection) -> None: + def do_upgrade(conn: ConnectionPlus) -> None: log.info(f'Starting database upgrade version {from_version} ' f'to {to_version}') @@ -378,7 +379,7 @@ def perform_db_upgrade(conn: SomeConnection, version: int=-1) -> None: @upgrader -def perform_db_upgrade_0_to_1(conn: SomeConnection) -> None: +def perform_db_upgrade_0_to_1(conn: ConnectionPlus) -> None: """ Perform the upgrade from version 0 to version 1 @@ -419,7 +420,7 @@ def perform_db_upgrade_0_to_1(conn: SomeConnection) -> None: @upgrader -def perform_db_upgrade_1_to_2(conn: SomeConnection) -> None: +def perform_db_upgrade_1_to_2(conn: ConnectionPlus) -> None: """ Perform the upgrade from version 1 to version 2 @@ -623,7 +624,7 @@ def _2to3_get_paramspecs(conn: SomeConnection, @upgrader -def perform_db_upgrade_2_to_3(conn: SomeConnection) -> None: +def perform_db_upgrade_2_to_3(conn: ConnectionPlus) -> None: """ Perform the upgrade from version 2 to version 3 @@ -811,11 +812,11 @@ def make_connection_plus_from(conn: SomeConnection) -> ConnectionPlus: if not isinstance(conn, ConnectionPlus): conn_plus = ConnectionPlus(conn) else: - conn_plus = cast(ConnectionPlus, conn) + conn_plus = conn return conn_plus -def init_db(conn: SomeConnection)->None: +def init_db(conn: ConnectionPlus)->None: with atomic(conn) as conn: transaction(conn, _experiment_table_schema) transaction(conn, _runs_table_schema) @@ -842,7 +843,7 @@ def is_column_in_table(conn: SomeConnection, table: str, column: str) -> bool: return False -def insert_column(conn: SomeConnection, table: str, name: str, +def insert_column(conn: ConnectionPlus, table: str, name: str, paramtype: Optional[str] = None) -> None: """Insert new column to a table @@ -947,7 +948,7 @@ def insert_values(conn: SomeConnection, return c.lastrowid -def insert_many_values(conn: SomeConnection, +def insert_many_values(conn: ConnectionPlus, formatted_name: str, columns: List[str], values: List[VALUES], @@ -1466,7 +1467,7 @@ def get_last_experiment(conn: SomeConnection) -> Optional[int]: return c.fetchall()[0][0] -def get_runs(conn: SomeConnection, +def get_runs(conn: ConnectionPlus, exp_id: Optional[int] = None)->List[sqlite3.Row]: """ Get a list of runs. @@ -1543,7 +1544,7 @@ def data_sets(conn: SomeConnection) -> List[sqlite3.Row]: return c.fetchall() -def _insert_run(conn: SomeConnection, exp_id: int, name: str, +def _insert_run(conn: ConnectionPlus, exp_id: int, name: str, guid: str, parameters: Optional[List[ParamSpec]] = None, ): @@ -1725,7 +1726,7 @@ def get_paramspec(conn: SomeConnection, return parspec -def update_run_description(conn: SomeConnection, run_id: int, +def update_run_description(conn: ConnectionPlus, run_id: int, description: str) -> None: """ Update the run_description field for the given run_id. The description @@ -1746,7 +1747,7 @@ def update_run_description(conn: SomeConnection, run_id: int, conn.cursor().execute(sql, (description, run_id)) -def add_parameter(conn: SomeConnection, +def add_parameter(conn: ConnectionPlus, formatted_name: str, *parameter: ParamSpec): """ @@ -1787,7 +1788,7 @@ def add_parameter(conn: SomeConnection, *parameter) -def _add_parameters_to_layout_and_deps(conn: SomeConnection, +def _add_parameters_to_layout_and_deps(conn: ConnectionPlus, formatted_name: str, *parameter: ParamSpec) -> sqlite3.Cursor: # get the run_id @@ -1848,7 +1849,7 @@ def _validate_table_name(table_name: str) -> bool: return valid -def _create_run_table(conn: SomeConnection, +def _create_run_table(conn: ConnectionPlus, formatted_name: str, parameters: Optional[List[ParamSpec]] = None, values: Optional[VALUES] = None @@ -1893,7 +1894,7 @@ def _create_run_table(conn: SomeConnection, transaction(conn, query) -def create_run(conn: SomeConnection, exp_id: int, name: str, +def create_run(conn: ConnectionPlus, exp_id: int, name: str, guid: str, parameters: Optional[List[ParamSpec]]=None, values: List[Any] = None, @@ -1972,7 +1973,7 @@ def get_metadata_from_run_id(conn: SomeConnection, run_id: int) -> Dict: return metadata -def insert_meta_data(conn: SomeConnection, row_id: int, table_name: str, +def insert_meta_data(conn: ConnectionPlus, row_id: int, table_name: str, metadata: Dict[str, Any]) -> None: """ Insert new metadata column and add values. Note that None is not a valid @@ -2007,7 +2008,7 @@ def update_meta_data(conn: SomeConnection, row_id: int, table_name: str, update_where(conn, table_name, 'rowid', row_id, **metadata) -def add_meta_data(conn: SomeConnection, +def add_meta_data(conn: ConnectionPlus, row_id: int, metadata: Dict[str, Any], table_name: str = "runs") -> None: diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 31701481895..6128fe59b9a 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -77,7 +77,7 @@ def test_atomic(): match_str = re.escape('atomic context manager only accepts ConnectionPlus ' 'database connection objects.') with pytest.raises(ValueError, match=match_str): - with atomic(sqlite_conn): # type: ignore + with atomic(sqlite_conn): pass conn_plus = ConnectionPlus(sqlite_conn) From c8454e5ee4540749f46ec968677ef220d355bb14 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 10:11:57 +0100 Subject: [PATCH 193/719] Unify deprecation messages for deprecated DataSet methods --- qcodes/dataset/data_set.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 9d1d24e107b..0e8a712dab6 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -576,8 +576,8 @@ def add_results(self, results: List[Dict[str, VALUE]]) -> int: values) return len_before_add - @deprecate(reason='it is an experimental functionality, and is most ' - 'probably will be removed soon.') + @deprecate(reason='it is an experimental functionality, and is likely ' + 'to be removed soon.') def modify_result(self, index: int, results: Dict[str, VALUES]) -> None: """ Modify a logically single result of existing parameters @@ -608,8 +608,8 @@ def modify_result(self, index: int, results: Dict[str, VALUES]) -> None: list(results.values()) ) - @deprecate(reason='it is an experimental functionality, and it is not ' - 'known whether it will remain or it will be removed.', + @deprecate(reason='it is an experimental functionality, and is likely ' + 'to be removed soon.', alternative='modify_result') def modify_results(self, start_index: int, updates: List[Dict[str, VALUES]]): @@ -653,8 +653,8 @@ def modify_results(self, start_index: int, flattened_keys, flattened_values) - @deprecate(reason='it is an experimental functionality, and it is not ' - 'known whether it will remain or it will be removed.', + @deprecate(reason='it is an experimental functionality, and is likely ' + 'to be removed soon.', alternative='add_parameter, add_result, add_results') def add_parameter_values(self, spec: ParamSpec, values: VALUES): """ From 326375fcd40b91c8d568e4155e8c2b3557dabfb8 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 10:24:25 +0100 Subject: [PATCH 194/719] Remove not needed test about unsubscribe_all and unsubscribe methods of DataSet which used to make atomic connections never commit --- qcodes/tests/dataset/test_subscribing.py | 46 ------------------------ 1 file changed, 46 deletions(-) diff --git a/qcodes/tests/dataset/test_subscribing.py b/qcodes/tests/dataset/test_subscribing.py index 8d862f7b332..397283664ef 100644 --- a/qcodes/tests/dataset/test_subscribing.py +++ b/qcodes/tests/dataset/test_subscribing.py @@ -196,49 +196,3 @@ def test_subscription_from_config_wrong_name(dataset): assert 'test_subscriber' not in qcodes.config.subscription.subscribers with pytest.raises(RuntimeError): sub_id_c = dataset.subscribe_from_config('test_subscriber') - - -def test_unsubscribe_all_makes_atomic_connections_never_commit( - dataset, basic_subscriber): - xparam = ParamSpec(name='x', paramtype='numeric') - dataset.add_parameter(xparam) - - sub_id = dataset.subscribe(basic_subscriber, min_wait=0, min_count=1, - state={}) - - assert len(dataset.subscribers) == 1 - assert list(dataset.subscribers.keys()) == [sub_id] - - dataset.unsubscribe_all() - - dataset.add_result({'x': 1}) - - shadow_ds = make_shadow_dataset(dataset) - try: - assert dataset.get_data('x') == [[1]] - assert shadow_ds.get_data('x') == [[1]] - finally: - shadow_ds.conn.close() - - -def test_unsubscribe_makes_atomic_connections_never_commit( - dataset, basic_subscriber): - xparam = ParamSpec(name='x', paramtype='numeric') - dataset.add_parameter(xparam) - - sub_id = dataset.subscribe(basic_subscriber, min_wait=0, min_count=1, - state={}) - - assert len(dataset.subscribers) == 1 - assert list(dataset.subscribers.keys()) == [sub_id] - - dataset.unsubscribe(sub_id) - - dataset.add_result({'x': 1}) - - shadow_ds = make_shadow_dataset(dataset) - try: - assert dataset.get_data('x') == [[1]] - assert shadow_ds.get_data('x') == [[1]] - finally: - shadow_ds.conn.close() From 3ad23c18255f801707b3d37a047157d41e330898 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 10:30:35 +0100 Subject: [PATCH 195/719] Add transaction function that removes a trigger from database --- qcodes/dataset/sqlite_base.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 7c20af7f9e2..1d973bba428 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -2135,3 +2135,16 @@ def _both_zero(run_id: int, conn, guid_comps) -> None: log.info(f'Updating run number {run_id}...') actions[(loc == 0, ws == 0)](run_id, conn, guid_comps) + + +def remove_trigger(conn: SomeConnection, trigger_id: str) -> None: + """ + Removes a trigger with a given id if it exists. + + Note that this transaction is not atomic! + + Args: + conn: database connection object + name: id of the trigger + """ + transaction(conn, f"DROP TRIGGER IF EXISTS {trigger_id};") From d62b72ef46bdfe09affc2a93251e7db3782f8974 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 10:31:25 +0100 Subject: [PATCH 196/719] Do not redefine self.conn in DataSet when doing atomic transactions + use remove_trigger from sqlite_base --- qcodes/dataset/data_set.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 0e8a712dab6..caf4ac09938 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -33,7 +33,7 @@ get_run_timestamp_from_run_id, get_completed_timestamp_from_run_id, update_run_description, - run_exists) + run_exists, remove_trigger) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -602,8 +602,8 @@ def modify_result(self, index: int, results: Dict[str, VALUES]) -> None: if param not in self.paramspecs.keys(): raise ValueError(f'No such parameter: {param}.') - with atomic(self.conn) as self.conn: - modify_values(self.conn, self.table_name, index, + with atomic(self.conn) as conn: + modify_values(conn, self.table_name, index, list(results.keys()), list(results.values()) ) @@ -646,8 +646,8 @@ def modify_results(self, start_index: int, values = [list(val.values()) for val in updates] flattened_values = [item for sublist in values for item in sublist] - with atomic(self.conn) as self.conn: - modify_many_values(self.conn, + with atomic(self.conn) as conn: + modify_many_values(conn, self.table_name, start_index, flattened_keys, @@ -676,8 +676,8 @@ def add_parameter_values(self, spec: ParamSpec, values: VALUES): len(values) )) - with atomic(self.conn) as self.conn: - add_parameter(self.conn, self.table_name, spec) + with atomic(self.conn) as conn: + add_parameter(conn, self.table_name, spec) # now add values! results = [{spec.name: value} for value in values] self.add_results(results) @@ -813,25 +813,22 @@ def unsubscribe(self, uuid: str) -> None: """ Remove subscriber with the provided uuid """ - with atomic(self.conn) as self.conn: + with atomic(self.conn) as conn: sub = self.subscribers[uuid] - self._remove_trigger(sub.trigger_id) + remove_trigger(conn, sub.trigger_id) sub.schedule_stop() sub.join() del self.subscribers[uuid] - def _remove_trigger(self, name): - transaction(self.conn, f"DROP TRIGGER IF EXISTS {name};") - def unsubscribe_all(self): """ Remove all subscribers """ sql = "select * from sqlite_master where type = 'trigger';" triggers = atomic_transaction(self.conn, sql).fetchall() - with atomic(self.conn) as self.conn: + with atomic(self.conn) as conn: for trigger in triggers: - self._remove_trigger(trigger['name']) + remove_trigger(conn, trigger['name']) for sub in self.subscribers.values(): sub.schedule_stop() sub.join() From 05b2617a213b9679b57cee309970486629c6c5cd Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Mon, 26 Nov 2018 11:37:31 +0100 Subject: [PATCH 197/719] Ensure ConnectionPlus is used within DataSet --- qcodes/dataset/data_set.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index caf4ac09938..a8811d02d27 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -33,7 +33,9 @@ get_run_timestamp_from_run_id, get_completed_timestamp_from_run_id, update_run_description, - run_exists, remove_trigger) + run_exists, remove_trigger, + make_connection_plus_from, + SomeConnection) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -185,7 +187,7 @@ def _clean_up(self) -> None: class DataSet(Sized): def __init__(self, path_to_db: str=None, run_id: Optional[int]=None, - conn=None, + conn: Optional[SomeConnection]=None, exp_id=None, name: str=None, specs: SPECS=None, @@ -221,7 +223,8 @@ def __init__(self, path_to_db: str=None, "This is not allowed.") self._path_to_db = path_to_db or get_DB_location() - self.conn = conn or connect(self.path_to_db) + self.conn = make_connection_plus_from(conn) if conn is not None else \ + connect(self.path_to_db) self._run_id = run_id self._debug = False From b523b59ed7650fabda43471a6fe2c8f087c5f25f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 16:23:34 -0800 Subject: [PATCH 198/719] 1) Example notebook should not execute 2) Processed PR comments. --- .../Qcodes example with Stahl.ipynb | 41 +++-- qcodes/instrument_drivers/stahl/stahl.py | 147 ++++++++++++------ 2 files changed, 135 insertions(+), 53 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index f4a21ccf526..c7cc7841481 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -27,7 +27,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Stahl HV (serial:171, firmware:None) in 0.07s\n" + "Connected to: Stahl HV (serial:171, firmware:None) in 0.08s\n" ] } ], @@ -49,7 +49,7 @@ } ], "source": [ - "v = stahl.channel[4].voltage(2)\n", + "stahl.channel[4].voltage(2)\n", "v = stahl.channel[4].voltage()\n", "print(v)" ] @@ -63,12 +63,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "-1.997\n" + "-2.0\n" ] } ], "source": [ - "v = stahl.channel[4].voltage(-2)\n", + "stahl.channel[4].voltage(-2)\n", "v = stahl.channel[4].voltage()\n", "print(v)" ] @@ -87,7 +87,7 @@ } ], "source": [ - "v = stahl.channel[4].voltage(0)\n", + "stahl.channel[4].voltage(0)\n", "v = stahl.channel[4].voltage()\n", "print(v)" ] @@ -100,7 +100,7 @@ { "data": { "text/plain": [ - "0.002" + "2e-06" ] }, "execution_count": 6, @@ -120,7 +120,7 @@ { "data": { "text/plain": [ - "26.3" + "'A'" ] }, "execution_count": 7, @@ -129,7 +129,7 @@ } ], "source": [ - "stahl.temperature()" + "stahl.channel[0].current.unit" ] }, { @@ -140,7 +140,7 @@ { "data": { "text/plain": [ - "False" + "25.9" ] }, "execution_count": 8, @@ -148,6 +148,26 @@ "output_type": "execute_result" } ], + "source": [ + "stahl.temperature()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "stahl.channel[1].is_locked()" ] @@ -177,6 +197,9 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.7" + }, + "nbsphinx": { + "execute": "never" } }, "nbformat": 4, diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 45a672024ef..4d9e0779402 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -6,6 +6,7 @@ import re import numpy as np import logging +from collections import OrderedDict from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Numbers @@ -14,6 +15,41 @@ logger = logging.getLogger() +class UnexpectedInstrumentResponse(Exception): + def __init__(self): + super().__init__( + "Unexpected instrument response. Perhaps the model of the " + "instrument does not match the drivers expectation or a " + "firmware upgrade has taken place. Please get in touch " + "with a QCoDeS core developer" + ) + + +def chain(*functions: Callable) -> Callable: + """ + The output of the first callable is piped to the input of the second, etc. + + Example: + >>> def f(): + >>>> return "1.2" + >>> chain(f, float)() # return 1.2 as float + """ + def make_tuple(args): + if not isinstance(args, tuple): + return args, + return args + + def inner(*args): + result = args + for fun in functions: + new_args = make_tuple(result) + result = fun(*new_args) + + return result + + return inner + + class StahlChannel(InstrumentChannel): """ A Stahl source channel @@ -23,17 +59,22 @@ class StahlChannel(InstrumentChannel): name channel_number """ + + acknowledge_reply = chr(6) + def __init__(self, parent: VisaInstrument, name: str, channel_number: int): super().__init__(parent, name) self._channel_string = f"{channel_number:02d}" self._channel_number = channel_number - self._acknowledge_reply = chr(6) self.add_parameter( "voltage", get_cmd=f"{self.parent.identifier} U{self._channel_string}", - get_parser=self._stahl_get_parser("V"), + get_parser=chain( + self.parent.regex_parser("([+\-]\d+,\d+) V$"), + self._string_to_float() + ), set_cmd=self._set_voltage, unit="V", vals=Numbers( @@ -45,8 +86,13 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): self.add_parameter( "current", get_cmd=f"{self.parent.identifier} I{self._channel_string}", - get_parser=self._stahl_get_parser("mA"), - unit="mA", + get_parser=chain( + self.parent.regex_parser("([+\-]\d+,\d+) mA$"), + self._string_to_float( + scale_factor=1/1000 # We want results in Ampere + ) + ), + unit="A", ) self.add_parameter( @@ -55,25 +101,20 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): ) @staticmethod - def _stahl_get_parser(unit: str) -> Callable: + def _string_to_float( + decimal_separator: str=",", + scale_factor: float=1 + ) -> Callable: """ - Upon querying the voltage and current, the response from the instrument - is `+/-yy,yyy V` or `+/-yy,yyy mA'. We strip the unit and replace the - comma with a dot. - - Args: - unit: The unit to strip - - Return: - parser: Parse a response to a float + Querying the voltage and current gives back strings containing a + comma denoting a decimal symbol (e.g. 1,4 = 1.4). Correct this + madness (and send an angry email to Stahl) """ - regex = f"([\+\-]\d+,\d+ ){unit}$" + def converter(string): + sane_str = string.replace(decimal_separator, ".") + return float(sane_str) * scale_factor - def parser(response: str) -> float: - result, = re.search(regex, response).groups() - return float(result.replace(",", ".")) - - return parser + return converter def _set_voltage(self, voltage: float) -> None: """ @@ -91,8 +132,8 @@ def _set_voltage(self, voltage: float) -> None: send_string = f"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}" response = self.ask(send_string) - if response != self._acknowledge_reply: - logger.warning(f"Command {send_string} did not produce an acknowledge reply") + if response != self.acknowledge_reply: + self.log.warning(f"Command {send_string} did not produce an acknowledge reply") def _get_lock_status(self) -> bool: """ @@ -109,10 +150,10 @@ def _get_lock_status(self) -> bool: header_fmt="empty" ) - chnr = self._channel_number - 1 - channel_group = chnr // 4 + channel_index = self._channel_number - 1 + channel_group = channel_index // 4 lock_code_group = response[channel_group] - return format(lock_code_group, "b")[chnr % 4 + 1] == "1" + return format(lock_code_group, "b")[channel_index % 4 + 1] == "1" class Stahl(VisaInstrument): @@ -152,39 +193,57 @@ def __init__(self, name: str, address: str): self.add_parameter( "temperature", - get_cmd=self._get_temperature, + get_cmd=f"{self.identifier} TEMP", + get_parser=chain( + self.regex_parser("TEMP (.*)°C"), + float + ), unit="C" ) self.connect_message() - def _get_temperature(self) -> float: + def ask_raw(self, cmd: str) -> str: """ - When querying the temperature a non-ascii character to denote - the degree symbol '°' is present in the return string. For this - reason, we cannot use the `ask` method as it will attempt to - decode the response with utf-8, which will fail. We need to - manually set the decoding to latin-1 + Sometimes the instrument returns non-ascii characters in response strings + Manually adjust the encoding to latin-1 """ - send_string = f"{self.identifier} TEMP" - self.write(send_string) + self.visa_log.debug(f"Querying: {cmd}") + self.visa_handle.write(cmd) response = self.visa_handle.read(encoding="latin-1") - temperature_string, = re.search("TEMP (.*)°C", response).groups() - return float(temperature_string) + self.visa_log.debug(f"Response: {response}") + return response @staticmethod - def _parse_idn_string(ind_string) -> Dict[str, Any]: + def regex_parser(match_string: str) -> Callable: + + regex = re.compile(match_string) + + def parser(input_string): + result = regex.search(input_string) + if result is None: + raise UnexpectedInstrumentResponse() + + result_groups = result.groups() + if len(result_groups) == 1: + return result_groups[0] + else: + return result_groups + + return parser + + def _parse_idn_string(self, ind_string) -> Dict[str, Any]: """ Return: dict with keys: "model", "serial_number", "voltage_range", "n_channels", "output_type" """ - groups = re.search( - "(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]", - ind_string - ).groups() + idn_parser = self.regex_parser( + "(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]" + ) + parsed_idn = idn_parser(ind_string) - id_parsers: Dict[str, Callable] = { + id_parsers: Dict[str, Callable] = OrderedDict({ "model": str, "serial_number": str, "voltage_range": float, @@ -196,11 +255,11 @@ def _parse_idn_string(ind_string) -> Dict[str, Any]: "s": "steerer", "m": "bipolar milivolt" }.get - } + }) return { name: id_parsers[name](value) - for name, value in zip(id_parsers.keys(), groups) + for name, value in zip(id_parsers.keys(), parsed_idn) } def get_idn(self) -> Dict[str, Optional[str]]: From 7a544631f73ec367f29387c278f0441484b120c4 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 16:35:56 -0800 Subject: [PATCH 199/719] More type hints --- .../driver_examples/Qcodes example with Stahl.ipynb | 8 ++++---- qcodes/instrument_drivers/stahl/stahl.py | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index c7cc7841481..22d3182a4f5 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -27,7 +27,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Stahl HV (serial:171, firmware:None) in 0.08s\n" + "Connected to: Stahl HV (serial:171, firmware:None) in 0.06s\n" ] } ], @@ -44,7 +44,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.001\n" + "2.0\n" ] } ], @@ -63,7 +63,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "-2.0\n" + "-1.997\n" ] } ], @@ -140,7 +140,7 @@ { "data": { "text/plain": [ - "25.9" + "26.9" ] }, "execution_count": 8, diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 4d9e0779402..093767d887b 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -2,7 +2,7 @@ This is a driver for the Stahl power supplies """ -from typing import Dict, Optional, Any, Callable +from typing import Dict, Optional, Any, Callable, Union, Sequence import re import numpy as np import logging @@ -107,7 +107,7 @@ def _string_to_float( ) -> Callable: """ Querying the voltage and current gives back strings containing a - comma denoting a decimal symbol (e.g. 1,4 = 1.4). Correct this + comma denoting a decimal separator (e.g. 1,4 = 1.4). Correct this madness (and send an angry email to Stahl) """ def converter(string): @@ -219,7 +219,7 @@ def regex_parser(match_string: str) -> Callable: regex = re.compile(match_string) - def parser(input_string): + def parser(input_string: str) -> Union[str, Sequence[str]]: result = regex.search(input_string) if result is None: raise UnexpectedInstrumentResponse() @@ -243,7 +243,7 @@ def _parse_idn_string(self, ind_string) -> Dict[str, Any]: ) parsed_idn = idn_parser(ind_string) - id_parsers: Dict[str, Callable] = OrderedDict({ + converters: Dict[str, Callable] = OrderedDict({ "model": str, "serial_number": str, "voltage_range": float, @@ -258,8 +258,8 @@ def _parse_idn_string(self, ind_string) -> Dict[str, Any]: }) return { - name: id_parsers[name](value) - for name, value in zip(id_parsers.keys(), parsed_idn) + name: converter(value) + for (name, converter), value in zip(converters.items(), parsed_idn) } def get_idn(self) -> Dict[str, Optional[str]]: From a002bd097f896b4d27c4a13af0e9dd659bc459e0 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 17:16:15 -0800 Subject: [PATCH 200/719] Add tests --- .../Qcodes example with Stahl.ipynb | 60 +++++++++++++++++++ qcodes/instrument_drivers/stahl/stahl.py | 18 ++++-- qcodes/tests/drivers/test_stahl.py | 36 +++++++++++ 3 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 qcodes/tests/drivers/test_stahl.py diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 22d3182a4f5..8da3df5affb 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -172,6 +172,66 @@ "stahl.channel[1].is_locked()" ] }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "parser = Stahl.regex_parser(\"^QCoDeS is (.*)$\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "result = parser(\"QCoDeS is Cool\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Cool'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "ename": "UnexpectedInstrumentResponse", + "evalue": "Unexpected instrument response. Perhaps the model of the instrument does not match the drivers expectation or a firmware upgrade has taken place. Please get in touch with a QCoDeS core developer", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mUnexpectedInstrumentResponse\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mparser\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"QCoDe is Cool\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\sochatoo\\development\\qcodes\\qcodes\\instrument_drivers\\stahl\\stahl.py\u001b[0m in \u001b[0;36mparser\u001b[1;34m(input_string)\u001b[0m\n\u001b[0;32m 223\u001b[0m \"\"\"\n\u001b[0;32m 224\u001b[0m \u001b[0mregex\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mre\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmatch_string\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 225\u001b[1;33m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 226\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mparser\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput_string\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSequence\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 227\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mregex\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msearch\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput_string\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mUnexpectedInstrumentResponse\u001b[0m: Unexpected instrument response. Perhaps the model of the instrument does not match the drivers expectation or a firmware upgrade has taken place. Please get in touch with a QCoDeS core developer" + ] + } + ], + "source": [ + "parser(\"QCoDe is Cool\")" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 093767d887b..596fb68554c 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -72,7 +72,7 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): "voltage", get_cmd=f"{self.parent.identifier} U{self._channel_string}", get_parser=chain( - self.parent.regex_parser("([+\-]\d+,\d+) V$"), + self.parent.regex_parser(r"([+\-]\d+,\d+) V$"), self._string_to_float() ), set_cmd=self._set_voltage, @@ -87,7 +87,7 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): "current", get_cmd=f"{self.parent.identifier} I{self._channel_string}", get_parser=chain( - self.parent.regex_parser("([+\-]\d+,\d+) mA$"), + self.parent.regex_parser(r"([+\-]\d+,\d+) mA$"), self._string_to_float( scale_factor=1/1000 # We want results in Ampere ) @@ -216,7 +216,15 @@ def ask_raw(self, cmd: str) -> str: @staticmethod def regex_parser(match_string: str) -> Callable: + """ + Example: + >>> parser = Stahl.regex_parser("^QCoDeS is (.*)$") + >>> result = parser("QCoDeS is Cool") # Will return 'Cool' + Raises: + UnexpectedInstrumentResponse if a match could not be found with + regular expressions + """ regex = re.compile(match_string) def parser(input_string: str) -> Union[str, Sequence[str]]: @@ -232,16 +240,16 @@ def parser(input_string: str) -> Union[str, Sequence[str]]: return parser - def _parse_idn_string(self, ind_string) -> Dict[str, Any]: + def _parse_idn_string(self, idn_string) -> Dict[str, Any]: """ Return: dict with keys: "model", "serial_number", "voltage_range", "n_channels", "output_type" """ idn_parser = self.regex_parser( - "(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]" + r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]" ) - parsed_idn = idn_parser(ind_string) + parsed_idn = idn_parser(idn_string) converters: Dict[str, Callable] = OrderedDict({ "model": str, diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py new file mode 100644 index 00000000000..e0db5429b5b --- /dev/null +++ b/qcodes/tests/drivers/test_stahl.py @@ -0,0 +1,36 @@ +import pytest + +from qcodes.instrument_drivers.stahl import Stahl +from qcodes.instrument_drivers.stahl.stahl import UnexpectedInstrumentResponse, chain + + +def test_parse_simple(): + parser = Stahl.regex_parser("^QCoDeS is (.*)$") + result = parser("QCoDeS is Cool") + assert result == "Cool" + + with pytest.raises(UnexpectedInstrumentResponse): + parser("QCoDe is Cool") + + +def test_parse_tuple(): + parser = Stahl.regex_parser(r"^QCoDeS version is (\d),(\d)$") + a, b = parser("QCoDeS version is 3,4") + + assert a == "3" + assert b == "4" + + +def test_chain(): + + def f(a, b): + return int(a) + int(b) + + parser = chain( + Stahl.regex_parser(r"^QCoDeS version is (\d),(\d)$"), + f + ) + + answer = parser("QCoDeS version is 3,4") + assert answer == 7 + From dded1fb228ff80068282e64fb22db7b2df1ece50 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 17:23:15 -0800 Subject: [PATCH 201/719] add docstring to test functions --- qcodes/tests/drivers/test_stahl.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py index e0db5429b5b..e17246805db 100644 --- a/qcodes/tests/drivers/test_stahl.py +++ b/qcodes/tests/drivers/test_stahl.py @@ -5,6 +5,11 @@ def test_parse_simple(): + """ + Test that we can parse simple messages from the instrument + and that the proper exception is raised when the received + response does not match the expectation + """ parser = Stahl.regex_parser("^QCoDeS is (.*)$") result = parser("QCoDeS is Cool") assert result == "Cool" @@ -14,6 +19,9 @@ def test_parse_simple(): def test_parse_tuple(): + """ + Test that we can extract multiple values from a string + """ parser = Stahl.regex_parser(r"^QCoDeS version is (\d),(\d)$") a, b = parser("QCoDeS version is 3,4") @@ -22,7 +30,9 @@ def test_parse_tuple(): def test_chain(): - + """ + Test chaining of callables + """ def f(a, b): return int(a) + int(b) From fc4e8a561ec1adedc6f9917115811108b9825bf5 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 17:24:44 -0800 Subject: [PATCH 202/719] clean up example notebook --- .../Qcodes example with Stahl.ipynb | 60 ------------------- 1 file changed, 60 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 8da3df5affb..22d3182a4f5 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -172,66 +172,6 @@ "stahl.channel[1].is_locked()" ] }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "parser = Stahl.regex_parser(\"^QCoDeS is (.*)$\")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "result = parser(\"QCoDeS is Cool\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Cool'" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "ename": "UnexpectedInstrumentResponse", - "evalue": "Unexpected instrument response. Perhaps the model of the instrument does not match the drivers expectation or a firmware upgrade has taken place. Please get in touch with a QCoDeS core developer", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mUnexpectedInstrumentResponse\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mparser\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"QCoDe is Cool\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mc:\\users\\sochatoo\\development\\qcodes\\qcodes\\instrument_drivers\\stahl\\stahl.py\u001b[0m in \u001b[0;36mparser\u001b[1;34m(input_string)\u001b[0m\n\u001b[0;32m 223\u001b[0m \"\"\"\n\u001b[0;32m 224\u001b[0m \u001b[0mregex\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mre\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmatch_string\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 225\u001b[1;33m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 226\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mparser\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput_string\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[0mUnion\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mSequence\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 227\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mregex\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msearch\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput_string\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mUnexpectedInstrumentResponse\u001b[0m: Unexpected instrument response. Perhaps the model of the instrument does not match the drivers expectation or a firmware upgrade has taken place. Please get in touch with a QCoDeS core developer" - ] - } - ], - "source": [ - "parser(\"QCoDe is Cool\")" - ] - }, { "cell_type": "code", "execution_count": null, From 886cda10ed0bdf61e6eaf00f4d01371eef5c2c2e Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 17:48:30 -0800 Subject: [PATCH 203/719] bugfix: the output type was not extracted from the IDN string --- .../Qcodes example with Stahl.ipynb | 113 +++++++++++++++++- qcodes/instrument_drivers/stahl/stahl.py | 2 +- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 22d3182a4f5..3dac68d516c 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -44,7 +44,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.0\n" + "2.001\n" ] } ], @@ -140,7 +140,7 @@ { "data": { "text/plain": [ - "26.9" + "25.9" ] }, "execution_count": 8, @@ -172,6 +172,115 @@ "stahl.channel[1].is_locked()" ] }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'Stahl' object and its delegates have no attribute 'output_type'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mstahl\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moutput_type\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\sochatoo\\development\\qcodes\\qcodes\\utils\\helpers.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 418\u001b[0m raise AttributeError(\n\u001b[0;32m 419\u001b[0m \"'{}' object and its delegates have no attribute '{}'\".format(\n\u001b[1;32m--> 420\u001b[1;33m self.__class__.__name__, key))\n\u001b[0m\u001b[0;32m 421\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 422\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__dir__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'Stahl' object and its delegates have no attribute 'output_type'" + ] + } + ], + "source": [ + "stahl.output_type" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "idn_str = stahl.ask(\"IDN\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'model': 'HV', 'serial_number': '171', 'voltage_range': 5.0, 'n_channels': 10}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stahl._parse_idn_string(idn_str)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'HV171 005 10 b'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "idn_str" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "import re " + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "regex = \"(HV|BS)(\\d{3}) (\\d{3}) (\\d{2}) ([buqsm])\"" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('HV', '171', '005', '10', 'b')" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "re.search(regex, idn_str).groups()" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 596fb68554c..f0d4dec1bdd 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -247,7 +247,7 @@ def _parse_idn_string(self, idn_string) -> Dict[str, Any]: "n_channels", "output_type" """ idn_parser = self.regex_parser( - r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) [buqsm]" + r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) ([buqsm])" ) parsed_idn = idn_parser(idn_string) From 63f7a4ff90e9d28d54c5b81c0ac7a2b32996d928 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 26 Nov 2018 17:48:51 -0800 Subject: [PATCH 204/719] bugfix: the output type was not extracted from the IDN string --- .../Qcodes example with Stahl.ipynb | 97 +------------------ 1 file changed, 4 insertions(+), 93 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index 3dac68d516c..d279f493e00 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -174,111 +174,22 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'Stahl' object and its delegates have no attribute 'output_type'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mstahl\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moutput_type\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mc:\\users\\sochatoo\\development\\qcodes\\qcodes\\utils\\helpers.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m 418\u001b[0m raise AttributeError(\n\u001b[0;32m 419\u001b[0m \"'{}' object and its delegates have no attribute '{}'\".format(\n\u001b[1;32m--> 420\u001b[1;33m self.__class__.__name__, key))\n\u001b[0m\u001b[0;32m 421\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 422\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__dir__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mAttributeError\u001b[0m: 'Stahl' object and its delegates have no attribute 'output_type'" - ] - } - ], - "source": [ - "stahl.output_type" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "idn_str = stahl.ask(\"IDN\")" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'model': 'HV', 'serial_number': '171', 'voltage_range': 5.0, 'n_channels': 10}" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "stahl._parse_idn_string(idn_str)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'HV171 005 10 b'" + "'bipolar'" ] }, - "execution_count": 19, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "idn_str" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "import re " - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "regex = \"(HV|BS)(\\d{3}) (\\d{3}) (\\d{2}) ([buqsm])\"" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('HV', '171', '005', '10', 'b')" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "re.search(regex, idn_str).groups()" + "stahl.output_type" ] }, { From 494bdc6967b12bfe41cc04cd42a227f94dc013fd Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 27 Nov 2018 10:13:34 +0100 Subject: [PATCH 205/719] Add safety measures against old source DB versions --- qcodes/dataset/database_extract_runs.py | 14 +++++++++- .../dataset/test_database_extract_runs.py | 28 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 865585915b8..d11d2bffade 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -9,6 +9,7 @@ connect, create_run, format_table_name, + get_db_version_and_newest_available_version, get_exp_ids_from_run_ids, get_last_experiment, get_matching_exp_ids, @@ -23,7 +24,8 @@ def extract_runs_into_db(source_db_path: str, - target_db_path: str, *run_ids: int) -> None: + target_db_path: str, *run_ids: int, + upgrade_source_db: bool=False) -> None: """ Extract a selection of runs into another DB file. All runs must come from the same experiment. They will be added to an experiment with the same name @@ -35,7 +37,17 @@ def extract_runs_into_db(source_db_path: str, target_db_path: Path to the target DB file. The target DB file will be created if it does not exist. run_ids: The run_ids of the runs to copy into the target DB file + upgrade_source_db: If the source DB is found to be in a version that is + not the newest, should it be upgraded? """ + # Check for versions + (s_v, new_v) = get_db_version_and_newest_available_version(source_db_path) + if s_v < new_v and not upgrade_source_db: + warn(f'Source DB version is {s_v}, but this function needs it to be' + f' in version {new_v}. Run this function again with ' + 'upgrade_source_db=True to auto-upgrade the source DB file.') + return + source_conn = connect(source_db_path) # Validate that all runs are in the source database diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index ada869522f2..988083b41ae 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -1,11 +1,13 @@ from os.path import getmtime from contextlib import contextmanager import re +import os import pytest import numpy as np -from qcodes.dataset.sqlite_base import connect, get_experiments +import qcodes.tests.dataset +from qcodes.dataset.sqlite_base import get_experiments from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.data_set import (DataSet, load_by_guid, load_by_counter, load_by_id) @@ -397,3 +399,27 @@ def test_load_by_X_functions(two_empty_temp_db_connections, test_ds = load_by_counter(1, 1, target_conn) assert source_ds_2_2.the_same_dataset_as(test_ds) + + +def test_old_versions_not_touched(two_empty_temp_db_connections): + + _, target_conn = two_empty_temp_db_connections + + target_path = path_to_dbfile(target_conn) + + fixturepath = os.sep.join(qcodes.tests.dataset.__file__.split(os.sep)[:-1]) + fixturepath = os.path.join(fixturepath, + 'fixtures', 'db_files', 'version2', + 'some_runs.db') + if not os.path.exists(fixturepath): + pytest.skip("No db-file fixtures found. You can generate test db-files" + " using the scripts in the legacy_DB_generation folder") + with raise_if_file_changed(fixturepath): + with pytest.warns(UserWarning) as warning: + extract_runs_into_db(fixturepath, target_path, 1) + expected_mssg = ('Source DB version is 2, but this ' + 'function needs it to be in version 3. ' + 'Run this function again with ' + 'upgrade_source_db=True to auto-upgrade ' + 'the source DB file.') + assert warning[0].message.args[0] == expected_mssg From b9d5f52d6547c7c1ed7737d0c2971cf9cebdeb39 Mon Sep 17 00:00:00 2001 From: qSaevar <39056113+qSaevar@users.noreply.github.com> Date: Tue, 16 Oct 2018 14:22:17 +0200 Subject: [PATCH 206/719] [DEM-564] Create a new HDAWG8 driver from ZI example (#1) * [DEM-564] Create a new HDAWG8 driver from ZI example --- qcodes/instrument_drivers/ZI/ZIHDAWG8 | 198 ++++++++++++++++++++++++++ qcodes/tests/drivers/test_zihdawg8.py | 86 +++++++++++ 2 files changed, 284 insertions(+) create mode 100644 qcodes/instrument_drivers/ZI/ZIHDAWG8 create mode 100644 qcodes/tests/drivers/test_zihdawg8.py diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8 b/qcodes/instrument_drivers/ZI/ZIHDAWG8 new file mode 100644 index 00000000000..cfe3a2e2988 --- /dev/null +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8 @@ -0,0 +1,198 @@ +import json +import time +from functools import partial + +import zhinst +import zhinst.utils + +from qcodes import Instrument +from qcodes.utils import validators as validators + + +class ZIHDAWG8(Instrument): + """ + QCoDeS driver for ZI HDAWG8. + + Requires ZI LabOne software to be installed on the computer running QCoDeS (tested using LabOne (18.05.54618) + and firmware (53866). + Furthermore, the Data Server and Web Server must be running and a connection + between the two must be made. + """ + + def __init__(self, name: str, device_id: str, **kwargs) -> None: + """ + Create an instance of the instrument. + + Args: + name (str): The internal QCoDeS name of the instrument + device_ID (str): The device name as listed in the web server. + """ + super().__init__(name, **kwargs) + self.api_level = 6 + (self.daq, self.device, self.props) = zhinst.utils.create_api_session(device_id, self.api_level, + required_devtype='HDAWG') + self.awg_module = self.daq.awgModule() + self.awg_module.set('awgModule/device', self.device) + self.awg_module.execute() + node_tree = self.download_device_node_tree() + self.create_parameters_from_node_tree(node_tree) + + def enable_channel(self, channel_number): + """ + Enable a signal output, turns on a blue LED on the device. + Args: + channel_number (int): Output channel that should be enabled. + + Returns: None + """ + self.set('sigouts_{}_on'.format(channel_number), 1) + + def disable_channel(self, channel_number): + """ + Disable a signal output, turns off a blue LED on the device. + Args: + channel_number (int): Output channel that should be disabled. + + Returns: None + """ + self.set('sigouts_{}_on'.format(channel_number), 0) + + def start_awg(self, awg_number): + """ + Activate an AWG + Args: + awg_number (int): The AWG that should be enabled. + + Returns: None + """ + self.set('awgs_{}_enable'.format(awg_number), 1) + + def stop_awg(self, awg_number): + """ + Deactivate an AWG + Args: + awg_number (int): The AWG that should be disabled. + + Returns: None + """ + self.set('awgs_{}_enable'.format(awg_number), 0) + + def upload_sequence_program(self, awg, sequence_program): + """ + Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. + Args: + awg (int): The AWG that the sequence program will be uploaded to. + sequence_program (str): A sequence program that should be played on the device. + Returns (int): 0: Compilation was successful with no warnings. + 1: Compilation was successful but with warnings. + """ + self.awg_module.set('awgModule/index', awg) + self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) + while self.awg_module.getInt('awgModule/compiler/status') == -1: + time.sleep(0.1) + + if self.awg_module.getInt('awgModule/compiler/status') == 1: + raise Exception(self.awg_module.getString('awgModule/compiler/statusstring')) + while self.awg_module.getDouble('awgModule/progress') < 1.0: + time.sleep(0.1) + + return self.awg_module.getInt('awgModule/compiler/status') + + def upload_waveform(self, awg, waveform, index): + """ + Upload a waveform to the device memory at a given index. + Node: There needs to be a place holder on the device as this only replaces a data in the device memory and there + for does not allocate new memory space. + Args: + awg (int): The AWG where waveform should be uploaded to. + waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) + index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index + corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. + + Returns: None + + """ + self.set('awgs_{}_waveform_index'.format(awg), index) + self.daq.sync() + self.set('awgs_{}_waveform_data'.format(awg), waveform) + + def set_channel_grouping(self, group): + """ + Set the channel grouping mode of the device. + + Args: + group (int): 0: Use the outputs in groups of 2. One sequencer program controls 2 outputs. + 1: Use the outputs in groups of 4. One sequencer program controls 4 outputs. + 2: Use the outputs in groups of 8. One sequencer program controls 8 outputs. + Returns: None + + """ + self.set('system_awg_channelgrouping', group) + + def create_parameters_from_node_tree(self, parameters): + """ + Create QuCoDeS parameters from the device node tree. + Args: + parameters (dict): A device node tree. + + Returns: None + + """ + for parameter in parameters.values(): + getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ + 'Properties'] else None + setter = partial(self._setter, parameter['Node'], parameter['Type']) if 'Write' in parameter[ + 'Properties'] else None + options = validators.Enum(*[int(val) for val in parameter['Options'].keys()]) \ + if parameter['Type'] == 'Integer (enumerated)' else None + parameter_name = self._generate_parameter_name(parameter['Node']) + self.add_parameter(name=parameter_name, + set_cmd=setter, + get_cmd=getter, + vals=options, + docstring=parameter['Description'], + unit=parameter['Unit'] + ) + + @staticmethod + def _generate_parameter_name(node): + values = node.split('/') + return '_'.join(values[2:]).lower() + + def download_device_node_tree(self, flags=0): + """ + Args: + flags: ziPython.ziListEnum.settingsonly -> 0x08 + Returns only nodes which are marked as setting + ziPython.ziListEnum.streamingonly -> 0x10 + Returns only streaming nodes + ziPython.ziListEnum.subscribedonly -> 0x20 + Returns only subscribed nodes + ziPython.ziListEnum.basechannel -> 0x40 + Return only one instance of a node in case of multiple channels + Or any combination of flags can be used. + + Returns: A dictionary of the device node tree. + """ + node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) + return json.loads(node_tree) + + def _setter(self, name, param_type, value): + if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + self.daq.setInt(name, value) + elif param_type == "Double": + self.daq.setDouble(name, value) + elif param_type == "String": + self.daq.setString(name, value) + elif param_type == "ZIVectorData": + self.daq.vectorWrite(name, value) + + def _getter(self, name, param_type): + if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + self.daq.getInt(name) + elif param_type == "Double": + self.daq.getDouble(name) + elif param_type == "String": + self.daq.getString(name) + elif param_type == "ZIVectorData": + self.daq.vectorRead(name) diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py new file mode 100644 index 00000000000..19f9b3e5c5d --- /dev/null +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -0,0 +1,86 @@ +import unittest +from unittest.mock import patch, MagicMock + +import zhinst + +import qcodes +from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 +from qcodes.utils import validators + + +class TestZIHDAWG8(unittest.TestCase): + def setUp(self): + self.node_tree = {"/DEV8049/SYSTEM/AWG/CHANNELGROUPING": { + "Node": "/DEV8049/SYSTEM/AWG/CHANNELGROUPING", + "Description": "Sets the channel grouping mode of the device.", + "Properties": "Read, Write, Setting", + "Type": "Integer (enumerated)", + "Unit": "None", + "Options": { + "0": "Use the outputs in groups of 2. One sequencer program controls 2 outputs ", + "1": "Use the outputs in groups of 4. One sequencer program controls 4 outputs ", + "2": "Use the outputs in groups of 8. One sequencer program controls 8 outputs " + } + }, "/DEV8049/SIGOUTS/0/ON": { + "Node": "/DEV8049/SIGOUTS/0/ON", + "Description": "Enabling/Disabling the Signal Output. Corresponds to the blue LED indicator", + "Properties": "Read, Write, Setting", + "Type": "Integer (64 bit)", + "Unit": "None" + }, "/DEV8049/SYSTEM/OWNER": { + "Node": "/DEV8049/SYSTEM/OWNER", + "Description": "Returns the current owner of the device (IP).", + "Properties": "Read", + "Type": "String", + "Unit": "None" + }, "/DEV8049/SINES/0/AMPLITUDES/0": { + "Node": "/DEV8049/SINES/0/AMPLITUDES/0", + "Description": "Sets the peak amplitude that the sine signal contributes to the signal output. Note that\ + the last index is either 0 or 1 and will map to the pair of outputs given by the first index.\ + (e.g. sines/3/amplitudes/0 corresponds to wave output 2)", + "Properties": "Read, Write, Setting", + "Type": "Double", + "Unit": "None" + }, "/DEV8049/AWGS/1/WAVEFORM/MEMORYUSAGE": { + "Node": "/DEV8049/AWGS/1/WAVEFORM/MEMORYUSAGE", + "Description": "Amount of the used waveform data relative to the device cache memory. The cache memory \ + provides space for 32 kSa of waveform data. Memory Usage over 100% means that waveforms must be loaded from\ + the main memory (128 MSa per channel) during playback, which can lead to delays.", + "Properties": "Read", + "Type": "Double", + "Unit": "%" + }} + + def test_create_parameters_from_node_tree(self): + with patch.object(zhinst.utils, 'create_api_session', return_value=3 * (MagicMock(),)), \ + patch.object(qcodes.instrument_drivers.ZI.ZIHDAWG8.ZIHDAWG8, 'download_device_node_tree', + return_value=self.node_tree): + hdawg8 = ZIHDAWG8('Name', 'dev-test') + + self.assertIn('system_awg_channelgrouping', hdawg8.parameters) + with self.assertRaises(ValueError): + hdawg8.system_awg_channelgrouping.set(4) + self.assertEqual('None', hdawg8.system_awg_channelgrouping.unit) + self.assertEqual('system_awg_channelgrouping', hdawg8.system_awg_channelgrouping.name) + self.assertIsNotNone(hdawg8.system_awg_channelgrouping.vals) + self.assertIsInstance(hdawg8.system_awg_channelgrouping.vals, validators.Enum) + + self.assertIn('sigouts_0_on', hdawg8.parameters) + self.assertEqual('None', hdawg8.sigouts_0_on.unit) + self.assertEqual('sigouts_0_on', hdawg8.sigouts_0_on.name) + self.assertIsNone(hdawg8.sigouts_0_on.vals) + + self.assertIn('system_owner', hdawg8.parameters) + self.assertEqual('None', hdawg8.system_owner.unit) + self.assertEqual('system_owner', hdawg8.system_owner.name) + self.assertIsNone(hdawg8.system_owner.vals) + + self.assertIn('sines_0_amplitudes_0', hdawg8.parameters) + self.assertEqual('None', hdawg8.sines_0_amplitudes_0.unit) + self.assertEqual('sines_0_amplitudes_0', hdawg8.sines_0_amplitudes_0.name) + self.assertIsNone(hdawg8.sines_0_amplitudes_0.vals) + + self.assertIn('awgs_1_waveform_memoryusage', hdawg8.parameters) + self.assertEqual('%', hdawg8.awgs_1_waveform_memoryusage.unit) + self.assertEqual('awgs_1_waveform_memoryusage', hdawg8.awgs_1_waveform_memoryusage.name) + self.assertIsNone(hdawg8.awgs_1_waveform_memoryusage.vals) From e231ac5189f3c4c0c6694159ef583248ad505960 Mon Sep 17 00:00:00 2001 From: qSaevar <39056113+qSaevar@users.noreply.github.com> Date: Fri, 19 Oct 2018 13:22:47 +0200 Subject: [PATCH 207/719] [DEM-525] Improve raw waveform upload speed (#2) * [DEM-525] Improve raw waveform upload speed --- .../ZI/{ZIHDAWG8 => ZIHDAWG8.py} | 78 ++++++++++++++++--- qcodes/tests/drivers/test_zihdawg8.py | 47 ++++++++++- 2 files changed, 113 insertions(+), 12 deletions(-) rename qcodes/instrument_drivers/ZI/{ZIHDAWG8 => ZIHDAWG8.py} (70%) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8 b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py similarity index 70% rename from qcodes/instrument_drivers/ZI/ZIHDAWG8 rename to qcodes/instrument_drivers/ZI/ZIHDAWG8.py index cfe3a2e2988..361b3103f16 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8 +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -1,4 +1,7 @@ +import csv import json +import os +import textwrap import time from functools import partial @@ -77,16 +80,69 @@ def stop_awg(self, awg_number): """ self.set('awgs_{}_enable'.format(awg_number), 0) - def upload_sequence_program(self, awg, sequence_program): + def waveform_to_csv(self, wave_name, *waveforms): + """ + Write waveforms to a CSV file in the modules data directory so that it can be referenced and used in a + sequence program. If more than one waveform is provided they will be played simultaneously but on separate + outputs. + + Args: + wave_name: Name of the CSV file, is used by a sequence program. + waveforms (list): One or more waveforms that are to be written to a CSV file. Note if there are more than + one waveforms then they have to be of equal length, if not the longer ones will be truncated. + + Returns: None + + """ + data_dir = self.awg_module.getString('awgModule/directory') + wave_dir = os.path.join(data_dir, "awg", "waves") + if not os.path.isdir(wave_dir): + raise Exception("AWG module wave directory {} does not exist or is not a directory".format(wave_dir)) + csv_file = os.path.join(wave_dir, wave_name + '.csv') + with open(csv_file, "w", newline='') as f: + writer = csv.writer(f, delimiter=';') + writer.writerows(zip(*waveforms)) + + @staticmethod + def generate_csv_sequence_program(wave_names, channels=None): + """ + Generates and returns a sequencing program that plays the given waves on the given channels. There has to be a + CSV file with a corresponding name to a wave in wave_names. + Args: + wave_names (list): List of wave names that are to be played. + channels (list, optional): Channels to play the waveforms on. + + Returns (str): A sequencing program that can be uploaded to the device. + + """ + awg_program = textwrap.dedent(""" + HEADER + while(true){ + playWave(WAVES); + } + """) + sequence_header = '// generated by {}\n'.format(__name__) + awg_program = awg_program.replace('HEADER', sequence_header) + if channels is None: + argument_string = ('"{}"' * len(wave_names)).replace('""', '", "') + waves = argument_string.format(*wave_names) + else: + argument_string = ('{}, "{}"' * len(wave_names)).replace('}"{', '}", {') + waves = argument_string.format(*[value for pair in zip(channels, wave_names) for value in pair]) + awg_program = awg_program.replace('WAVES', waves) + + return awg_program + + def upload_sequence_program(self, awg_number, sequence_program): """ Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. Args: - awg (int): The AWG that the sequence program will be uploaded to. + awg_number (int): The AWG that the sequence program will be uploaded to. sequence_program (str): A sequence program that should be played on the device. Returns (int): 0: Compilation was successful with no warnings. 1: Compilation was successful but with warnings. """ - self.awg_module.set('awgModule/index', awg) + self.awg_module.set('awgModule/index', awg_number) self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) while self.awg_module.getInt('awgModule/compiler/status') == -1: time.sleep(0.1) @@ -98,13 +154,13 @@ def upload_sequence_program(self, awg, sequence_program): return self.awg_module.getInt('awgModule/compiler/status') - def upload_waveform(self, awg, waveform, index): + def upload_waveform(self, awg_number, waveform, index): """ Upload a waveform to the device memory at a given index. Node: There needs to be a place holder on the device as this only replaces a data in the device memory and there for does not allocate new memory space. Args: - awg (int): The AWG where waveform should be uploaded to. + awg_number (int): The AWG where waveform should be uploaded to. waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. @@ -112,9 +168,9 @@ def upload_waveform(self, awg, waveform, index): Returns: None """ - self.set('awgs_{}_waveform_index'.format(awg), index) + self.set('awgs_{}_waveform_index'.format(awg_number), index) self.daq.sync() - self.set('awgs_{}_waveform_data'.format(awg), waveform) + self.set('awgs_{}_waveform_data'.format(awg_number), waveform) def set_channel_grouping(self, group): """ @@ -189,10 +245,10 @@ def _setter(self, name, param_type, value): def _getter(self, name, param_type): if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': - self.daq.getInt(name) + return self.daq.getInt(name) elif param_type == "Double": - self.daq.getDouble(name) + return self.daq.getDouble(name) elif param_type == "String": - self.daq.getString(name) + return self.daq.getString(name) elif param_type == "ZIVectorData": - self.daq.vectorRead(name) + return self.daq.vectorRead(name) diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 19f9b3e5c5d..ecc275f9ea3 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -1,10 +1,11 @@ +import textwrap import unittest from unittest.mock import patch, MagicMock import zhinst +from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 import qcodes -from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 from qcodes.utils import validators @@ -84,3 +85,47 @@ def test_create_parameters_from_node_tree(self): self.assertEqual('%', hdawg8.awgs_1_waveform_memoryusage.unit) self.assertEqual('awgs_1_waveform_memoryusage', hdawg8.awgs_1_waveform_memoryusage.name) self.assertIsNone(hdawg8.awgs_1_waveform_memoryusage.vals) + + def test_generate_csv_sequence_program(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + while(true){ + playWaves(1, "wave_1", 2, "wave_2", 3, "wave_3"); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3'], [1, 2, 3]) + self.assertEqual(expected, sequence_program) + + def test_generate_csv_sequence_program_no_channels(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + while(true){ + playWaves("wave_1", "wave_2", "wave_3"); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3']) + self.assertEqual(expected, sequence_program) + + def test_generate_csv_sequence_program_1_wave_no_channels(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + while(true){ + playWaves("wave_1"); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1']) + self.assertEqual(expected, sequence_program) + + def test_generate_csv_sequence_program_1_wave(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + while(true){ + playWaves(7, "wave_1"); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1'], [7]) + self.assertEqual(expected, sequence_program) From 147653baca21bace07e85a1c2810795153cb3636 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 16 Oct 2018 13:24:35 +0200 Subject: [PATCH 208/719] [DEM-564] Create a new HDAWG8 driver from ZI example --- qcodes/instrument_drivers/ZI/ZIHDAWG8 | 198 ++++++++++++++++++++++++++ qcodes/tests/drivers/test_zihdawg8.py | 7 +- 2 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 qcodes/instrument_drivers/ZI/ZIHDAWG8 diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8 b/qcodes/instrument_drivers/ZI/ZIHDAWG8 new file mode 100644 index 00000000000..f590b0b7e1a --- /dev/null +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8 @@ -0,0 +1,198 @@ +import json +import time +from functools import partial + +import zhinst +import zhinst.utils + +from qcodes import Instrument +from qcodes.utils import validators as validators + + +class ZIHDAWG8(Instrument): + """ + QCoDeS driver for ZI HDAWG8. + + Requires ZI LabOne software to be installed on the computer running QCoDeS (tested using LabOne (18.05.54618) + and firmware (53866). + Furthermore, the Data Server and Web Server must be running and a connection + between the two must be made. + """ + + def __init__(self, name: str, device_id: str, **kwargs) -> None: + """ + Create an instance of the instrument. + + Args: + name (str): The internal QCoDeS name of the instrument + device_ID (str): The device name as listed in the web server. + """ + super().__init__(name, **kwargs) + self.api_level = 6 + (self.daq, self.device, self.props) = zhinst.utils.create_api_session(device_id, self.api_level, + required_devtype='HDAWG') + self.awg_module = self.daq.awgModule() + self.awg_module.set('awgModule/device', self.device) + self.awg_module.execute() + node_tree = self.download_device_node_tree() + self.create_parameters_from_node_tree(node_tree) + + def enable_channel(self, channel_number): + """ + Enable a signal output, turns on a blue LED on the device. + Args: + channel_number (int): Output channel that should be enabled. + + Returns: None + """ + self.set('sigouts_{}_on'.format(channel_number), 1) + + def disable_channel(self, channel_number): + """ + Disable a signal output, turns off a blue LED on the device. + Args: + channel_number (int): Output channel that should be disabled. + + Returns: None + """ + self.set('sigouts_{}_on'.format(channel_number), 0) + + def start_awg(self, awg_number): + """ + Activate an AWG + Args: + awg_number (int): The AWG that should be enabled. + + Returns: None + """ + self.set('awgs_{}_enable'.format(awg_number), 1) + + def stop_awg(self, awg): + """ + Deactivate an AWG + Args: + awg (int): The AWG that should be disabled. + + Returns: None + """ + self.set('awgs_{}_enable'.format(awg), 0) + + def upload_sequence_program(self, awg, sequence_program): + """ + Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. + Args: + awg (int): The AWG that the sequence program will be uploaded to. + sequence_program (str): A sequence program that should be played on the device. + Returns (int): 0: Compilation was successful with no warnings. + 1: Compilation was successful but with warnings. + """ + self.awg_module.set('awgModule/index', awg) + self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) + while self.awg_module.getInt('awgModule/compiler/status') == -1: + time.sleep(0.1) + + if self.awg_module.getInt('awgModule/compiler/status') == 1: + raise Exception(self.awg_module.getString('awgModule/compiler/statusstring')) + while self.awg_module.getDouble('awgModule/progress') < 1.0: + time.sleep(0.1) + + return self.awg_module.getInt('awgModule/compiler/status') + + def upload_waveform(self, awg, waveform, index): + """ + Upload a waveform to the device memory at a given index. + Node: There needs to be a place holder on the device as this only replaces a data in the device memory and there + for does not allocate new memory space. + Args: + awg (int): The AWG where waveform should be uploaded to. + waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) + index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index + corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. + + Returns: None + + """ + self.set('awgs_{}_waveform_index'.format(awg), index) + self.daq.sync() + self.set('awgs_{}_waveform_data'.format(awg), waveform) + + def set_channel_grouping(self, group): + """ + Set the channel grouping mode of the device. + + Args: + group (int): 0: Use the outputs in groups of 2. One sequencer program controls 2 outputs. + 1: Use the outputs in groups of 4. One sequencer program controls 4 outputs. + 2: Use the outputs in groups of 8. One sequencer program controls 8 outputs. + Returns: None + + """ + self.set('system_awg_channelgrouping', group) + + def create_parameters_from_node_tree(self, parameters): + """ + Create QuCoDeS parameters from the device node tree. + Args: + parameters (dict): A device node tree. + + Returns: None + + """ + for parameter in parameters.values(): + getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ + 'Properties'] else None + setter = partial(self._setter, parameter['Node'], parameter['Type']) if 'Write' in parameter[ + 'Properties'] else None + options = validators.Enum(*[int(val) for val in parameter['Options'].keys()]) \ + if parameter['Type'] == 'Integer (enumerated)' else None + parameter_name = self._generate_parameter_name(parameter['Node']) + self.add_parameter(name=parameter_name, + set_cmd=setter, + get_cmd=getter, + vals=options, + docstring=parameter['Description'], + unit=parameter['Unit'] + ) + + @staticmethod + def _generate_parameter_name(node): + values = node.split('/') + return '_'.join(values[2:]).lower() + + def download_device_node_tree(self, flags=0): + """ + Args: + flags: ziPython.ziListEnum.settingsonly -> 0x08 + Returns only nodes which are marked as setting + ziPython.ziListEnum.streamingonly -> 0x10 + Returns only streaming nodes + ziPython.ziListEnum.subscribedonly -> 0x20 + Returns only subscribed nodes + ziPython.ziListEnum.basechannel -> 0x40 + Return only one instance of a node in case of multiple channels + Or any combination of flags can be used. + + Returns: A dictionary of the device node tree. + """ + node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) + return json.loads(node_tree) + + def _setter(self, name, param_type, value): + if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + self.daq.setInt(name, value) + elif param_type == "Double": + self.daq.setDouble(name, value) + elif param_type == "String": + self.daq.setString(name, value) + elif param_type == "ZIVectorData": + self.daq.vectorWrite(name, value) + + def _getter(self, name, param_type): + if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + self.daq.getInt(name) + elif param_type == "Double": + self.daq.getDouble(name) + elif param_type == "String": + self.daq.getString(name) + elif param_type == "ZIVectorData": + self.daq.vectorRead(name) diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index ecc275f9ea3..2c59d043945 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -1,11 +1,12 @@ +import sys import textwrap import unittest from unittest.mock import patch, MagicMock +sys.modules['zhinst'] = MagicMock(name='zhinst') import zhinst -from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 -import qcodes +from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 from qcodes.utils import validators @@ -54,7 +55,7 @@ def setUp(self): def test_create_parameters_from_node_tree(self): with patch.object(zhinst.utils, 'create_api_session', return_value=3 * (MagicMock(),)), \ - patch.object(qcodes.instrument_drivers.ZI.ZIHDAWG8.ZIHDAWG8, 'download_device_node_tree', + patch.object(ZIHDAWG8, 'download_device_node_tree', return_value=self.node_tree): hdawg8 = ZIHDAWG8('Name', 'dev-test') From 957fe7a7a0905306e2099c7980e5ddd717bb8950 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 16 Oct 2018 14:08:22 +0200 Subject: [PATCH 209/719] fixed small detail --- qcodes/instrument_drivers/ZI/ZIHDAWG8 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8 b/qcodes/instrument_drivers/ZI/ZIHDAWG8 index f590b0b7e1a..cfe3a2e2988 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8 +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8 @@ -67,15 +67,15 @@ class ZIHDAWG8(Instrument): """ self.set('awgs_{}_enable'.format(awg_number), 1) - def stop_awg(self, awg): + def stop_awg(self, awg_number): """ Deactivate an AWG Args: - awg (int): The AWG that should be disabled. + awg_number (int): The AWG that should be disabled. Returns: None """ - self.set('awgs_{}_enable'.format(awg), 0) + self.set('awgs_{}_enable'.format(awg_number), 0) def upload_sequence_program(self, awg, sequence_program): """ From 9af1dce4360826780a176dc183012f18053d1e0d Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 16 Oct 2018 16:04:54 +0200 Subject: [PATCH 210/719] Added a needed .py to ZIHDAWG8 --- qcodes/instrument_drivers/ZI/ZIHDAWG8 | 198 ----------------------- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 3 - 2 files changed, 201 deletions(-) delete mode 100644 qcodes/instrument_drivers/ZI/ZIHDAWG8 diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8 b/qcodes/instrument_drivers/ZI/ZIHDAWG8 deleted file mode 100644 index cfe3a2e2988..00000000000 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8 +++ /dev/null @@ -1,198 +0,0 @@ -import json -import time -from functools import partial - -import zhinst -import zhinst.utils - -from qcodes import Instrument -from qcodes.utils import validators as validators - - -class ZIHDAWG8(Instrument): - """ - QCoDeS driver for ZI HDAWG8. - - Requires ZI LabOne software to be installed on the computer running QCoDeS (tested using LabOne (18.05.54618) - and firmware (53866). - Furthermore, the Data Server and Web Server must be running and a connection - between the two must be made. - """ - - def __init__(self, name: str, device_id: str, **kwargs) -> None: - """ - Create an instance of the instrument. - - Args: - name (str): The internal QCoDeS name of the instrument - device_ID (str): The device name as listed in the web server. - """ - super().__init__(name, **kwargs) - self.api_level = 6 - (self.daq, self.device, self.props) = zhinst.utils.create_api_session(device_id, self.api_level, - required_devtype='HDAWG') - self.awg_module = self.daq.awgModule() - self.awg_module.set('awgModule/device', self.device) - self.awg_module.execute() - node_tree = self.download_device_node_tree() - self.create_parameters_from_node_tree(node_tree) - - def enable_channel(self, channel_number): - """ - Enable a signal output, turns on a blue LED on the device. - Args: - channel_number (int): Output channel that should be enabled. - - Returns: None - """ - self.set('sigouts_{}_on'.format(channel_number), 1) - - def disable_channel(self, channel_number): - """ - Disable a signal output, turns off a blue LED on the device. - Args: - channel_number (int): Output channel that should be disabled. - - Returns: None - """ - self.set('sigouts_{}_on'.format(channel_number), 0) - - def start_awg(self, awg_number): - """ - Activate an AWG - Args: - awg_number (int): The AWG that should be enabled. - - Returns: None - """ - self.set('awgs_{}_enable'.format(awg_number), 1) - - def stop_awg(self, awg_number): - """ - Deactivate an AWG - Args: - awg_number (int): The AWG that should be disabled. - - Returns: None - """ - self.set('awgs_{}_enable'.format(awg_number), 0) - - def upload_sequence_program(self, awg, sequence_program): - """ - Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. - Args: - awg (int): The AWG that the sequence program will be uploaded to. - sequence_program (str): A sequence program that should be played on the device. - Returns (int): 0: Compilation was successful with no warnings. - 1: Compilation was successful but with warnings. - """ - self.awg_module.set('awgModule/index', awg) - self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) - while self.awg_module.getInt('awgModule/compiler/status') == -1: - time.sleep(0.1) - - if self.awg_module.getInt('awgModule/compiler/status') == 1: - raise Exception(self.awg_module.getString('awgModule/compiler/statusstring')) - while self.awg_module.getDouble('awgModule/progress') < 1.0: - time.sleep(0.1) - - return self.awg_module.getInt('awgModule/compiler/status') - - def upload_waveform(self, awg, waveform, index): - """ - Upload a waveform to the device memory at a given index. - Node: There needs to be a place holder on the device as this only replaces a data in the device memory and there - for does not allocate new memory space. - Args: - awg (int): The AWG where waveform should be uploaded to. - waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) - index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index - corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. - - Returns: None - - """ - self.set('awgs_{}_waveform_index'.format(awg), index) - self.daq.sync() - self.set('awgs_{}_waveform_data'.format(awg), waveform) - - def set_channel_grouping(self, group): - """ - Set the channel grouping mode of the device. - - Args: - group (int): 0: Use the outputs in groups of 2. One sequencer program controls 2 outputs. - 1: Use the outputs in groups of 4. One sequencer program controls 4 outputs. - 2: Use the outputs in groups of 8. One sequencer program controls 8 outputs. - Returns: None - - """ - self.set('system_awg_channelgrouping', group) - - def create_parameters_from_node_tree(self, parameters): - """ - Create QuCoDeS parameters from the device node tree. - Args: - parameters (dict): A device node tree. - - Returns: None - - """ - for parameter in parameters.values(): - getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ - 'Properties'] else None - setter = partial(self._setter, parameter['Node'], parameter['Type']) if 'Write' in parameter[ - 'Properties'] else None - options = validators.Enum(*[int(val) for val in parameter['Options'].keys()]) \ - if parameter['Type'] == 'Integer (enumerated)' else None - parameter_name = self._generate_parameter_name(parameter['Node']) - self.add_parameter(name=parameter_name, - set_cmd=setter, - get_cmd=getter, - vals=options, - docstring=parameter['Description'], - unit=parameter['Unit'] - ) - - @staticmethod - def _generate_parameter_name(node): - values = node.split('/') - return '_'.join(values[2:]).lower() - - def download_device_node_tree(self, flags=0): - """ - Args: - flags: ziPython.ziListEnum.settingsonly -> 0x08 - Returns only nodes which are marked as setting - ziPython.ziListEnum.streamingonly -> 0x10 - Returns only streaming nodes - ziPython.ziListEnum.subscribedonly -> 0x20 - Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40 - Return only one instance of a node in case of multiple channels - Or any combination of flags can be used. - - Returns: A dictionary of the device node tree. - """ - node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) - return json.loads(node_tree) - - def _setter(self, name, param_type, value): - if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': - self.daq.setInt(name, value) - elif param_type == "Double": - self.daq.setDouble(name, value) - elif param_type == "String": - self.daq.setString(name, value) - elif param_type == "ZIVectorData": - self.daq.vectorWrite(name, value) - - def _getter(self, name, param_type): - if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': - self.daq.getInt(name) - elif param_type == "Double": - self.daq.getDouble(name) - elif param_type == "String": - self.daq.getString(name) - elif param_type == "ZIVectorData": - self.daq.vectorRead(name) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 361b3103f16..418ff87a106 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -1,7 +1,4 @@ -import csv import json -import os -import textwrap import time from functools import partial From 838b3cd274caa3197e6cbc092ea9409848b8d79d Mon Sep 17 00:00:00 2001 From: qSaevar Date: Mon, 22 Oct 2018 15:48:37 +0200 Subject: [PATCH 211/719] feat: Insturment driver for ZI HDAWG8 --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 418ff87a106..ce61436f259 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -1,4 +1,7 @@ +import csv import json +import os +import textwrap import time from functools import partial @@ -12,7 +15,6 @@ class ZIHDAWG8(Instrument): """ QCoDeS driver for ZI HDAWG8. - Requires ZI LabOne software to be installed on the computer running QCoDeS (tested using LabOne (18.05.54618) and firmware (53866). Furthermore, the Data Server and Web Server must be running and a connection @@ -22,7 +24,6 @@ class ZIHDAWG8(Instrument): def __init__(self, name: str, device_id: str, **kwargs) -> None: """ Create an instance of the instrument. - Args: name (str): The internal QCoDeS name of the instrument device_ID (str): The device name as listed in the web server. @@ -42,7 +43,6 @@ def enable_channel(self, channel_number): Enable a signal output, turns on a blue LED on the device. Args: channel_number (int): Output channel that should be enabled. - Returns: None """ self.set('sigouts_{}_on'.format(channel_number), 1) @@ -52,7 +52,6 @@ def disable_channel(self, channel_number): Disable a signal output, turns off a blue LED on the device. Args: channel_number (int): Output channel that should be disabled. - Returns: None """ self.set('sigouts_{}_on'.format(channel_number), 0) @@ -62,7 +61,6 @@ def start_awg(self, awg_number): Activate an AWG Args: awg_number (int): The AWG that should be enabled. - Returns: None """ self.set('awgs_{}_enable'.format(awg_number), 1) @@ -72,7 +70,6 @@ def stop_awg(self, awg_number): Deactivate an AWG Args: awg_number (int): The AWG that should be disabled. - Returns: None """ self.set('awgs_{}_enable'.format(awg_number), 0) @@ -89,7 +86,6 @@ def waveform_to_csv(self, wave_name, *waveforms): one waveforms then they have to be of equal length, if not the longer ones will be truncated. Returns: None - """ data_dir = self.awg_module.getString('awgModule/directory') wave_dir = os.path.join(data_dir, "awg", "waves") @@ -110,7 +106,6 @@ def generate_csv_sequence_program(wave_names, channels=None): channels (list, optional): Channels to play the waveforms on. Returns (str): A sequencing program that can be uploaded to the device. - """ awg_program = textwrap.dedent(""" HEADER @@ -161,9 +156,7 @@ def upload_waveform(self, awg_number, waveform, index): waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. - Returns: None - """ self.set('awgs_{}_waveform_index'.format(awg_number), index) self.daq.sync() @@ -172,13 +165,11 @@ def upload_waveform(self, awg_number, waveform, index): def set_channel_grouping(self, group): """ Set the channel grouping mode of the device. - Args: group (int): 0: Use the outputs in groups of 2. One sequencer program controls 2 outputs. 1: Use the outputs in groups of 4. One sequencer program controls 4 outputs. 2: Use the outputs in groups of 8. One sequencer program controls 8 outputs. Returns: None - """ self.set('system_awg_channelgrouping', group) @@ -187,9 +178,7 @@ def create_parameters_from_node_tree(self, parameters): Create QuCoDeS parameters from the device node tree. Args: parameters (dict): A device node tree. - Returns: None - """ for parameter in parameters.values(): getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ @@ -224,7 +213,6 @@ def download_device_node_tree(self, flags=0): ziPython.ziListEnum.basechannel -> 0x40 Return only one instance of a node in case of multiple channels Or any combination of flags can be used. - Returns: A dictionary of the device node tree. """ node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) @@ -249,3 +237,4 @@ def _getter(self, name, param_type): return self.daq.getString(name) elif param_type == "ZIVectorData": return self.daq.vectorRead(name) + From 906152b1f2d9db0a6f1adb31b3d3238a99bf1849 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 10:04:29 +0200 Subject: [PATCH 212/719] Added zhinst to setup.py --- environment.yml | 1 + qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/environment.yml b/environment.yml index 9bd0a05354a..02266992e2a 100644 --- a/environment.yml +++ b/environment.yml @@ -30,3 +30,4 @@ dependencies: - pip: - websockets>=3.2 - broadbean>=0.9.1 + - zhinst diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index ce61436f259..ce28a7e10b6 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -213,6 +213,7 @@ def download_device_node_tree(self, flags=0): ziPython.ziListEnum.basechannel -> 0x40 Return only one instance of a node in case of multiple channels Or any combination of flags can be used. + Returns: A dictionary of the device node tree. """ node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) @@ -237,4 +238,3 @@ def _getter(self, name, param_type): return self.daq.getString(name) elif param_type == "ZIVectorData": return self.daq.vectorRead(name) - diff --git a/setup.py b/setup.py index a90ef6a89be..0340193a1ac 100644 --- a/setup.py +++ b/setup.py @@ -124,4 +124,4 @@ def readme(): print(valueerror_template.format( module_name, module.__version__, min_version, extra)) except: - print(othererror_template.format(module_name)) + print(othererror_template.format(module_name)) \ No newline at end of file From 9ccc40b524fe70960b8d7c1c800d781f20f20430 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 10:21:14 +0200 Subject: [PATCH 213/719] Fixed broken tests --- qcodes/tests/drivers/test_zihdawg8.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 2c59d043945..9e7b7cea46d 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -92,7 +92,7 @@ def test_generate_csv_sequence_program(self): // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 while(true){ - playWaves(1, "wave_1", 2, "wave_2", 3, "wave_3"); + playWave(1, "wave_1", 2, "wave_2", 3, "wave_3"); } """) sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3'], [1, 2, 3]) @@ -103,7 +103,7 @@ def test_generate_csv_sequence_program_no_channels(self): // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 while(true){ - playWaves("wave_1", "wave_2", "wave_3"); + playWave("wave_1", "wave_2", "wave_3"); } """) sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3']) @@ -114,7 +114,7 @@ def test_generate_csv_sequence_program_1_wave_no_channels(self): // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 while(true){ - playWaves("wave_1"); + playWave("wave_1"); } """) sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1']) @@ -125,7 +125,7 @@ def test_generate_csv_sequence_program_1_wave(self): // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 while(true){ - playWaves(7, "wave_1"); + playWave(7, "wave_1"); } """) sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1'], [7]) From 14b05bdcf106f27b7ae2b704adcd38d4e12b67af Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 10:44:52 +0200 Subject: [PATCH 214/719] Fixed a docstring --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index ce28a7e10b6..f417dd22eac 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -213,7 +213,6 @@ def download_device_node_tree(self, flags=0): ziPython.ziListEnum.basechannel -> 0x40 Return only one instance of a node in case of multiple channels Or any combination of flags can be used. - Returns: A dictionary of the device node tree. """ node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) From 6cf167f4cd64df204e6c50f29a21099ea88feef4 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 13:48:09 +0200 Subject: [PATCH 215/719] Improving docstrings format --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 41 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index f417dd22eac..86a9dfb2879 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -24,6 +24,7 @@ class ZIHDAWG8(Instrument): def __init__(self, name: str, device_id: str, **kwargs) -> None: """ Create an instance of the instrument. + Args: name (str): The internal QCoDeS name of the instrument device_ID (str): The device name as listed in the web server. @@ -41,8 +42,10 @@ def __init__(self, name: str, device_id: str, **kwargs) -> None: def enable_channel(self, channel_number): """ Enable a signal output, turns on a blue LED on the device. + Args: channel_number (int): Output channel that should be enabled. + Returns: None """ self.set('sigouts_{}_on'.format(channel_number), 1) @@ -50,8 +53,10 @@ def enable_channel(self, channel_number): def disable_channel(self, channel_number): """ Disable a signal output, turns off a blue LED on the device. + Args: channel_number (int): Output channel that should be disabled. + Returns: None """ self.set('sigouts_{}_on'.format(channel_number), 0) @@ -59,8 +64,10 @@ def disable_channel(self, channel_number): def start_awg(self, awg_number): """ Activate an AWG + Args: awg_number (int): The AWG that should be enabled. + Returns: None """ self.set('awgs_{}_enable'.format(awg_number), 1) @@ -68,8 +75,10 @@ def start_awg(self, awg_number): def stop_awg(self, awg_number): """ Deactivate an AWG + Args: awg_number (int): The AWG that should be disabled. + Returns: None """ self.set('awgs_{}_enable'.format(awg_number), 0) @@ -101,6 +110,7 @@ def generate_csv_sequence_program(wave_names, channels=None): """ Generates and returns a sequencing program that plays the given waves on the given channels. There has to be a CSV file with a corresponding name to a wave in wave_names. + Args: wave_names (list): List of wave names that are to be played. channels (list, optional): Channels to play the waveforms on. @@ -128,9 +138,11 @@ def generate_csv_sequence_program(wave_names, channels=None): def upload_sequence_program(self, awg_number, sequence_program): """ Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. + Args: awg_number (int): The AWG that the sequence program will be uploaded to. sequence_program (str): A sequence program that should be played on the device. + Returns (int): 0: Compilation was successful with no warnings. 1: Compilation was successful but with warnings. """ @@ -149,13 +161,17 @@ def upload_sequence_program(self, awg_number, sequence_program): def upload_waveform(self, awg_number, waveform, index): """ Upload a waveform to the device memory at a given index. - Node: There needs to be a place holder on the device as this only replaces a data in the device memory and there - for does not allocate new memory space. + + Note: + There needs to be a place holder on the device as this only replaces a data in the device memory but + does not allocate new memory space. + Args: awg_number (int): The AWG where waveform should be uploaded to. waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. + Returns: None """ self.set('awgs_{}_waveform_index'.format(awg_number), index) @@ -165,10 +181,10 @@ def upload_waveform(self, awg_number, waveform, index): def set_channel_grouping(self, group): """ Set the channel grouping mode of the device. + Args: - group (int): 0: Use the outputs in groups of 2. One sequencer program controls 2 outputs. - 1: Use the outputs in groups of 4. One sequencer program controls 4 outputs. - 2: Use the outputs in groups of 8. One sequencer program controls 8 outputs. + group (int): 0: groups of 2. 1: groups of 4. 2: groups of 8 i.e., one sequencer program controls 8 outputs. + Returns: None """ self.set('system_awg_channelgrouping', group) @@ -176,8 +192,10 @@ def set_channel_grouping(self, group): def create_parameters_from_node_tree(self, parameters): """ Create QuCoDeS parameters from the device node tree. + Args: parameters (dict): A device node tree. + Returns: None """ for parameter in parameters.values(): @@ -204,15 +222,12 @@ def _generate_parameter_name(node): def download_device_node_tree(self, flags=0): """ Args: - flags: ziPython.ziListEnum.settingsonly -> 0x08 - Returns only nodes which are marked as setting - ziPython.ziListEnum.streamingonly -> 0x10 - Returns only streaming nodes - ziPython.ziListEnum.subscribedonly -> 0x20 - Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40 - Return only one instance of a node in case of multiple channels + flags: ziPython.ziListEnum.settingsonly -> 0x08: Returns only nodes which are marked as setting + ziPython.ziListEnum.streamingonly -> 0x10: Returns only streaming nodes + ziPython.ziListEnum.subscribedonly -> 0x20: Returns only subscribed nodes + ziPython.ziListEnum.basechannel -> 0x40: Return only one instance of a node in case of multiple channels Or any combination of flags can be used. + Returns: A dictionary of the device node tree. """ node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) From f2fd52ddc19f4ff8cff4b5ca0fc1f6bee16f89e2 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 16:21:34 +0200 Subject: [PATCH 216/719] Removed zhinst as a dependency --- environment.yml | 1 - qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 12 +++++++++--- qcodes/tests/drivers/test_zihdawg8.py | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/environment.yml b/environment.yml index 02266992e2a..9bd0a05354a 100644 --- a/environment.yml +++ b/environment.yml @@ -30,4 +30,3 @@ dependencies: - pip: - websockets>=3.2 - broadbean>=0.9.1 - - zhinst diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 86a9dfb2879..5228dcbd271 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -5,8 +5,13 @@ import time from functools import partial -import zhinst -import zhinst.utils +try: + import zhinst +except ImportError: + raise ImportError('''Could not find Zurich Instruments Lab One software. + Please refer to the Zi UHF-LI User Manual for + download and installation instructions. + ''') from qcodes import Instrument from qcodes.utils import validators as validators @@ -225,7 +230,8 @@ def download_device_node_tree(self, flags=0): flags: ziPython.ziListEnum.settingsonly -> 0x08: Returns only nodes which are marked as setting ziPython.ziListEnum.streamingonly -> 0x10: Returns only streaming nodes ziPython.ziListEnum.subscribedonly -> 0x20: Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40: Return only one instance of a node in case of multiple channels + ziPython.ziListEnum.basechannel -> 0x40: Return only one instance of a node in case of multiple + channels Or any combination of flags can be used. Returns: A dictionary of the device node tree. diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 9e7b7cea46d..ce9b16f91d2 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -10,6 +10,8 @@ from qcodes.utils import validators + + class TestZIHDAWG8(unittest.TestCase): def setUp(self): self.node_tree = {"/DEV8049/SYSTEM/AWG/CHANNELGROUPING": { From 60fb5bd86cfd01116785832f1dc646897e0e24fc Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 23 Oct 2018 16:35:53 +0200 Subject: [PATCH 217/719] small cleanup --- qcodes/tests/drivers/test_zihdawg8.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index ce9b16f91d2..9e7b7cea46d 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -10,8 +10,6 @@ from qcodes.utils import validators - - class TestZIHDAWG8(unittest.TestCase): def setUp(self): self.node_tree = {"/DEV8049/SYSTEM/AWG/CHANNELGROUPING": { From c9623ee325c3b7ddac3aacfac5893cff784c2a58 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 30 Oct 2018 21:35:22 +0100 Subject: [PATCH 218/719] setters for parameters should be False, not None, when not settable --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 5228dcbd271..6d2c262ab9d 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -5,13 +5,7 @@ import time from functools import partial -try: - import zhinst -except ImportError: - raise ImportError('''Could not find Zurich Instruments Lab One software. - Please refer to the Zi UHF-LI User Manual for - download and installation instructions. - ''') +import zhinst from qcodes import Instrument from qcodes.utils import validators as validators @@ -207,7 +201,7 @@ def create_parameters_from_node_tree(self, parameters): getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ 'Properties'] else None setter = partial(self._setter, parameter['Node'], parameter['Type']) if 'Write' in parameter[ - 'Properties'] else None + 'Properties'] else False options = validators.Enum(*[int(val) for val in parameter['Options'].keys()]) \ if parameter['Type'] == 'Integer (enumerated)' else None parameter_name = self._generate_parameter_name(parameter['Node']) @@ -258,3 +252,4 @@ def _getter(self, name, param_type): return self.daq.getString(name) elif param_type == "ZIVectorData": return self.daq.vectorRead(name) + From 7cd8dac7ecb5de69c59f85e6d0f1d30a9ea3cfc3 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Fri, 2 Nov 2018 09:46:57 +0100 Subject: [PATCH 219/719] rebase on master --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 6d2c262ab9d..5f8b4b027a0 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -251,5 +251,5 @@ def _getter(self, name, param_type): elif param_type == "String": return self.daq.getString(name) elif param_type == "ZIVectorData": - return self.daq.vectorRead(name) + return self.daq.getAsEvent(name) From 4a004bada89e625bcc019c6705bc61a560ed175d Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 6 Nov 2018 13:30:31 +0100 Subject: [PATCH 220/719] added import of zhinst.utils --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 5f8b4b027a0..b825a4a3fd9 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -6,6 +6,7 @@ from functools import partial import zhinst +import zhinst.utils from qcodes import Instrument from qcodes.utils import validators as validators From 804fb9f8f51be5cc39b2ab0cd00e08c92f1e98f1 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 6 Nov 2018 15:54:46 +0100 Subject: [PATCH 221/719] Addressing code style review comments --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 170 +++++++++++++---------- 1 file changed, 93 insertions(+), 77 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index b825a4a3fd9..53c6aa70bfa 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -4,6 +4,7 @@ import textwrap import time from functools import partial +from typing import Optional, Any import zhinst import zhinst.utils @@ -15,8 +16,8 @@ class ZIHDAWG8(Instrument): """ QCoDeS driver for ZI HDAWG8. - Requires ZI LabOne software to be installed on the computer running QCoDeS (tested using LabOne (18.05.54618) - and firmware (53866). + Requires ZI LabOne software to be installed on the computer running QCoDeS + (tested using LabOne (18.05.54618) and firmware (53866). Furthermore, the Data Server and Web Server must be running and a connection between the two must be made. """ @@ -26,96 +27,95 @@ def __init__(self, name: str, device_id: str, **kwargs) -> None: Create an instance of the instrument. Args: - name (str): The internal QCoDeS name of the instrument - device_ID (str): The device name as listed in the web server. + name: The internal QCoDeS name of the instrument + device_ID: The device name as listed in the web server. """ super().__init__(name, **kwargs) self.api_level = 6 - (self.daq, self.device, self.props) = zhinst.utils.create_api_session(device_id, self.api_level, - required_devtype='HDAWG') + (self.daq, self.device, self.props) = zhinst.utils.create_api_session( + device_id, self.api_level, + required_devtype='HDAWG') self.awg_module = self.daq.awgModule() self.awg_module.set('awgModule/device', self.device) self.awg_module.execute() node_tree = self.download_device_node_tree() self.create_parameters_from_node_tree(node_tree) - def enable_channel(self, channel_number): + def enable_channel(self, channel_number: int) -> None: """ Enable a signal output, turns on a blue LED on the device. Args: - channel_number (int): Output channel that should be enabled. - - Returns: None + channel_number: Output channel that should be enabled. """ self.set('sigouts_{}_on'.format(channel_number), 1) - def disable_channel(self, channel_number): + def disable_channel(self, channel_number: int) -> None: """ Disable a signal output, turns off a blue LED on the device. Args: - channel_number (int): Output channel that should be disabled. - - Returns: None + channel_number: Output channel that should be disabled. """ self.set('sigouts_{}_on'.format(channel_number), 0) - def start_awg(self, awg_number): + def start_awg(self, awg_number: int): """ Activate an AWG Args: - awg_number (int): The AWG that should be enabled. - - Returns: None + awg_number: The AWG that should be enabled. """ self.set('awgs_{}_enable'.format(awg_number), 1) - def stop_awg(self, awg_number): + def stop_awg(self, awg_number: int) -> None: """ Deactivate an AWG Args: - awg_number (int): The AWG that should be disabled. - - Returns: None + awg_number: The AWG that should be disabled. """ self.set('awgs_{}_enable'.format(awg_number), 0) - def waveform_to_csv(self, wave_name, *waveforms): + def waveform_to_csv(self, wave_name: str, *waveforms: list) -> None: """ - Write waveforms to a CSV file in the modules data directory so that it can be referenced and used in a - sequence program. If more than one waveform is provided they will be played simultaneously but on separate + Write waveforms to a CSV file in the modules data directory so that it + can be referenced and used in a sequence program. If more than one + waveform is provided they will be played simultaneously but on separate outputs. Args: wave_name: Name of the CSV file, is used by a sequence program. - waveforms (list): One or more waveforms that are to be written to a CSV file. Note if there are more than - one waveforms then they have to be of equal length, if not the longer ones will be truncated. - - Returns: None + waveforms: One or more waveforms that are to be written to a + CSV file. Note if there are more than one waveforms then they have + to be of equal length, if not the longer ones will be truncated. """ data_dir = self.awg_module.getString('awgModule/directory') wave_dir = os.path.join(data_dir, "awg", "waves") if not os.path.isdir(wave_dir): - raise Exception("AWG module wave directory {} does not exist or is not a directory".format(wave_dir)) + raise Exception( + "AWG module wave directory {} does not exist or is not a " + "directory".format( + wave_dir)) csv_file = os.path.join(wave_dir, wave_name + '.csv') with open(csv_file, "w", newline='') as f: writer = csv.writer(f, delimiter=';') writer.writerows(zip(*waveforms)) @staticmethod - def generate_csv_sequence_program(wave_names, channels=None): + def generate_csv_sequence_program(wave_names: list, + channels: Optional[list] = None) -> str: """ - Generates and returns a sequencing program that plays the given waves on the given channels. There has to be a - CSV file with a corresponding name to a wave in wave_names. + Generates and returns a sequencing program that plays the given waves on + the given channels. There has to be a CSV file with a corresponding + name to a wave in wave_names. Args: - wave_names (list): List of wave names that are to be played. - channels (list, optional): Channels to play the waveforms on. + wave_names: List of wave names that are to be played. + channels: Channels to play the waveforms on. - Returns (str): A sequencing program that can be uploaded to the device. + Returns: + A sequencing program that can be uploaded to the device. """ awg_program = textwrap.dedent(""" HEADER @@ -129,22 +129,29 @@ def generate_csv_sequence_program(wave_names, channels=None): argument_string = ('"{}"' * len(wave_names)).replace('""', '", "') waves = argument_string.format(*wave_names) else: - argument_string = ('{}, "{}"' * len(wave_names)).replace('}"{', '}", {') - waves = argument_string.format(*[value for pair in zip(channels, wave_names) for value in pair]) + argument_string = ('{}, "{}"' * len(wave_names)).replace('}"{', + '}", {') + waves = argument_string.format( + *[value for pair in zip(channels, wave_names) for value in + pair]) awg_program = awg_program.replace('WAVES', waves) return awg_program - def upload_sequence_program(self, awg_number, sequence_program): + def upload_sequence_program(self, awg_number: int, + sequence_program: str) -> int: """ - Uploads a sequence program to the device equivalent to using the the sequencer tab in the device's gui. + Uploads a sequence program to the device equivalent to using the the + sequencer tab in the device's gui. Args: - awg_number (int): The AWG that the sequence program will be uploaded to. - sequence_program (str): A sequence program that should be played on the device. + awg_number: The AWG that the sequence program will be uploaded to. + sequence_program: A sequence program that should be played on the + device. - Returns (int): 0: Compilation was successful with no warnings. - 1: Compilation was successful but with warnings. + Returns: + 0: Compilation was successful with no warnings. + 1: Compilation was successful but with warnings. """ self.awg_module.set('awgModule/index', awg_number) self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) @@ -152,58 +159,61 @@ def upload_sequence_program(self, awg_number, sequence_program): time.sleep(0.1) if self.awg_module.getInt('awgModule/compiler/status') == 1: - raise Exception(self.awg_module.getString('awgModule/compiler/statusstring')) + raise Exception( + self.awg_module.getString('awgModule/compiler/statusstring')) while self.awg_module.getDouble('awgModule/progress') < 1.0: time.sleep(0.1) return self.awg_module.getInt('awgModule/compiler/status') - def upload_waveform(self, awg_number, waveform, index): + def upload_waveform(self, awg_number: int, waveform: list, + index: int) -> None: """ Upload a waveform to the device memory at a given index. Note: - There needs to be a place holder on the device as this only replaces a data in the device memory but - does not allocate new memory space. + There needs to be a place holder on the device as this only replaces + a data in the device memory but does not allocate new memory space. Args: - awg_number (int): The AWG where waveform should be uploaded to. - waveform: An array of floating point values from -1.0 to 1.0, or integers in the range (-32768...+32768) - index: Index of the waveform that will be replaced. If there are more than 1 waveforms used then the index - corresponds to the position of the waveform in the Waveforms sub-tab of the AWG tab in the GUI. - - Returns: None + awg_number: The AWG where waveform should be uploaded to. + waveform: An array of floating point values from -1.0 to 1.0, or + integers in the range (-32768...+32768) + index: Index of the waveform that will be replaced. If there are + more than 1 waveforms used then the index corresponds to the + position of the waveform in the Waveforms sub-tab of the AWG tab + in the GUI. """ self.set('awgs_{}_waveform_index'.format(awg_number), index) self.daq.sync() self.set('awgs_{}_waveform_data'.format(awg_number), waveform) - def set_channel_grouping(self, group): + def set_channel_grouping(self, group: int) -> None: """ Set the channel grouping mode of the device. Args: - group (int): 0: groups of 2. 1: groups of 4. 2: groups of 8 i.e., one sequencer program controls 8 outputs. - - Returns: None + group: 0: groups of 2. 1: groups of 4. 2: groups of 8 i.e., one + sequencer program controls 8 outputs. """ self.set('system_awg_channelgrouping', group) - def create_parameters_from_node_tree(self, parameters): + def create_parameters_from_node_tree(self, parameters: dict) -> None: """ Create QuCoDeS parameters from the device node tree. Args: - parameters (dict): A device node tree. - - Returns: None + parameters: A device node tree. """ for parameter in parameters.values(): - getter = partial(self._getter, parameter['Node'], parameter['Type']) if 'Read' in parameter[ + getter = partial(self._getter, parameter['Node'], + parameter['Type']) if 'Read' in parameter[ 'Properties'] else None - setter = partial(self._setter, parameter['Node'], parameter['Type']) if 'Write' in parameter[ + setter = partial(self._setter, parameter['Node'], + parameter['Type']) if 'Write' in parameter[ 'Properties'] else False - options = validators.Enum(*[int(val) for val in parameter['Options'].keys()]) \ + options = validators.Enum( + *[int(val) for val in parameter['Options'].keys()]) \ if parameter['Type'] == 'Integer (enumerated)' else None parameter_name = self._generate_parameter_name(parameter['Node']) self.add_parameter(name=parameter_name, @@ -219,23 +229,29 @@ def _generate_parameter_name(node): values = node.split('/') return '_'.join(values[2:]).lower() - def download_device_node_tree(self, flags=0): + def download_device_node_tree(self, flags: int = 0) -> dict: """ Args: - flags: ziPython.ziListEnum.settingsonly -> 0x08: Returns only nodes which are marked as setting - ziPython.ziListEnum.streamingonly -> 0x10: Returns only streaming nodes - ziPython.ziListEnum.subscribedonly -> 0x20: Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40: Return only one instance of a node in case of multiple - channels + flags: ziPython.ziListEnum.settingsonly -> 0x08: + Returns only nodes which are marked as setting + ziPython.ziListEnum.streamingonly -> 0x10: + Returns only streaming nodes + ziPython.ziListEnum.subscribedonly -> 0x20: + Returns only subscribed nodes + ziPython.ziListEnum.basechannel -> 0x40: + Return only one instance of a node in case of multiple + channels Or any combination of flags can be used. - Returns: A dictionary of the device node tree. + Returns: + A dictionary of the device node tree. """ node_tree = self.daq.listNodesJSON('/{}/'.format(self.device), flags) return json.loads(node_tree) - def _setter(self, name, param_type, value): - if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + def _setter(self, name: str, param_type: str, value: Any) -> None: + if param_type == "Integer (64 bit)" or \ + param_type == 'Integer (enumerated)': self.daq.setInt(name, value) elif param_type == "Double": self.daq.setDouble(name, value) @@ -244,8 +260,9 @@ def _setter(self, name, param_type, value): elif param_type == "ZIVectorData": self.daq.vectorWrite(name, value) - def _getter(self, name, param_type): - if param_type == "Integer (64 bit)" or param_type == 'Integer (enumerated)': + def _getter(self, name: str, param_type: str) -> Any: + if param_type == "Integer (64 bit)" or \ + param_type == 'Integer (enumerated)': return self.daq.getInt(name) elif param_type == "Double": return self.daq.getDouble(name) @@ -253,4 +270,3 @@ def _getter(self, name, param_type): return self.daq.getString(name) elif param_type == "ZIVectorData": return self.daq.getAsEvent(name) - From 0cca32649b8da468b25eed59fd4afcede0b6c559 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Wed, 7 Nov 2018 09:02:10 +0100 Subject: [PATCH 222/719] Addressing review comments --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 11 +++++------ qcodes/tests/drivers/test_zihdawg8.py | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 53c6aa70bfa..bdba7ce30ee 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -6,7 +6,6 @@ from functools import partial from typing import Optional, Any -import zhinst import zhinst.utils from qcodes import Instrument @@ -17,7 +16,7 @@ class ZIHDAWG8(Instrument): """ QCoDeS driver for ZI HDAWG8. Requires ZI LabOne software to be installed on the computer running QCoDeS - (tested using LabOne (18.05.54618) and firmware (53866). + (tested using LabOne 18.05.54618 and firmware 53866). Furthermore, the Data Server and Web Server must be running and a connection between the two must be made. """ @@ -232,13 +231,13 @@ def _generate_parameter_name(node): def download_device_node_tree(self, flags: int = 0) -> dict: """ Args: - flags: ziPython.ziListEnum.settingsonly -> 0x08: + flags: ziPython.ziListEnum.settingsonly -> 0x08 Returns only nodes which are marked as setting - ziPython.ziListEnum.streamingonly -> 0x10: + ziPython.ziListEnum.streamingonly -> 0x10 Returns only streaming nodes - ziPython.ziListEnum.subscribedonly -> 0x20: + ziPython.ziListEnum.subscribedonly -> 0x20 Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40: + ziPython.ziListEnum.basechannel -> 0x40 Return only one instance of a node in case of multiple channels Or any combination of flags can be used. diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 9e7b7cea46d..73fd962754f 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -3,8 +3,9 @@ import unittest from unittest.mock import patch, MagicMock +sys.modules['zhinst.utils'] = MagicMock(name='zhinst.utils') sys.modules['zhinst'] = MagicMock(name='zhinst') -import zhinst +import zhinst.utils from qcodes.instrument_drivers.ZI.ZIHDAWG8 import ZIHDAWG8 from qcodes.utils import validators From 344fd17d96af73d5ff3b5d1841496caa7d1ae971 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Wed, 7 Nov 2018 12:59:56 +0100 Subject: [PATCH 223/719] Improved one docstring --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index bdba7ce30ee..551935cd897 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -231,15 +231,12 @@ def _generate_parameter_name(node): def download_device_node_tree(self, flags: int = 0) -> dict: """ Args: - flags: ziPython.ziListEnum.settingsonly -> 0x08 - Returns only nodes which are marked as setting - ziPython.ziListEnum.streamingonly -> 0x10 - Returns only streaming nodes - ziPython.ziListEnum.subscribedonly -> 0x20 - Returns only subscribed nodes - ziPython.ziListEnum.basechannel -> 0x40 - Return only one instance of a node in case of multiple - channels + flags: 0x08, Returns only nodes which are marked as setting + 0x10, Returns only streaming nodes + 0x20, Returns only subscribed nodes + 0x40, Return only one instance of a node in case of multiple + channels + Or any combination of flags can be used. Returns: From 4306e866156efec8b396843f1026fff089bc8276 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 13 Nov 2018 10:17:48 +0100 Subject: [PATCH 224/719] [DEM-612] Changed compile condition in upload_sequence_program --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 551935cd897..c0af5f45556 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -150,11 +150,12 @@ def upload_sequence_program(self, awg_number: int, Returns: 0: Compilation was successful with no warnings. - 1: Compilation was successful but with warnings. + 2: Compilation was successful but with warnings. """ self.awg_module.set('awgModule/index', awg_number) self.awg_module.set('awgModule/compiler/sourcestring', sequence_program) - while self.awg_module.getInt('awgModule/compiler/status') == -1: + while len(self.awg_module.get('awgModule/compiler/sourcestring') + ['compiler']['sourcestring'][0]) > 0: time.sleep(0.1) if self.awg_module.getInt('awgModule/compiler/status') == 1: From 2de26d0b53f18c7904e9630848a7a74b6e2b8054 Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 13 Nov 2018 16:28:30 +0100 Subject: [PATCH 225/719] Mentioned ziPython.ziListEnum.* in docstring --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index c0af5f45556..150dec323a6 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -232,13 +232,17 @@ def _generate_parameter_name(node): def download_device_node_tree(self, flags: int = 0) -> dict: """ Args: - flags: 0x08, Returns only nodes which are marked as setting - 0x10, Returns only streaming nodes - 0x20, Returns only subscribed nodes - 0x40, Return only one instance of a node in case of multiple - channels - - Or any combination of flags can be used. + flags: + ziPython.ziListEnum.settingsonly (0x08): Returns only nodes + which are marked as setting + ziPython.ziListEnum.streamingonly (0x10): Returns only + streaming nodes + ziPython.ziListEnum.subscribedonly (0x20): Returns only + subscribed nodes + ziPython.ziListEnum.basechannel (0x40): Return only one instance + of a node in case of multiple channels + + Or any combination of flags can be used. Returns: A dictionary of the device node tree. From c04dfbef9160c76847b2700bef72dc6dbe8e4b03 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 27 Nov 2018 11:05:21 +0100 Subject: [PATCH 226/719] Fix wrong use of connection --- qcodes/dataset/experiment_container.py | 10 +++++++--- qcodes/dataset/sqlite_base.py | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index b5baa5d1156..e3d56406407 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -12,6 +12,7 @@ connect, transaction, get_last_experiment, get_experiments, get_experiment_name_from_experiment_id, + get_runid_from_expid_and_counter, get_sample_name_from_experiment_id, SomeConnection) from qcodes.dataset.sqlite_base import new_experiment as ne @@ -126,7 +127,8 @@ def new_data_set(self, name, specs: SPECS = None, values=None, values: the values to associate with the parameters metadata: the metadata to associate with the dataset """ - return new_data_set(name, self.exp_id, specs, values, metadata) + return new_data_set(name, self.exp_id, specs, values, metadata, + conn=self.conn) def data_set(self, counter: int) -> DataSet: """ @@ -138,7 +140,9 @@ def data_set(self, counter: int) -> DataSet: Returns: the dataset """ - return load_by_counter(counter, self.exp_id) + run_id = get_runid_from_expid_and_counter(self.conn, self.exp_id, + counter) + return DataSet(run_id=run_id, conn=self.conn) def data_sets(self) -> List[DataSet]: """Get all the datasets of this experiment""" @@ -305,7 +309,7 @@ def load_experiment_by_name(name: str, raise ValueError(f"Many experiments matching your request" f" found:\n{_repr_str}") else: - e = Experiment(exp_id=rows[0]['exp_id']) + e = Experiment(exp_id=rows[0]['exp_id'], conn=conn) return e diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2ed21382990..39cb49ff17a 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1258,6 +1258,28 @@ def get_setpoints(conn: SomeConnection, return output +def get_runid_from_expid_and_counter(conn: SomeConnection, exp_id: int, + counter: int) -> int: + """ + Get the run_id of a run in the specified experiment with the specified + counter + + Args: + conn: connection to the database + exp_id: the exp_id of the experiment containing the run + counter: the intra-experiment run counter of that run + """ + sql = """ + SELECT run_id + FROM runs + WHERE result_counter= ? AND + exp_id = ? + """ + c = transaction(conn, sql, counter, exp_id) + run_id = one(c, 'run_id') + return run_id + + def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: """ Get the run_id of a run based on the guid From 15298c90e56ff8bf2ec3e0d28fc97d9f2fbf0dea Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 27 Nov 2018 11:05:27 +0100 Subject: [PATCH 227/719] Updated generate_csv_sequence_program due to a bug --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 70 ++++++++----- qcodes/tests/drivers/test_zihdawg8.py | 125 +++++++++++++++++++---- 2 files changed, 149 insertions(+), 46 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 150dec323a6..98fc94dfde1 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -4,8 +4,7 @@ import textwrap import time from functools import partial -from typing import Optional, Any - +from typing import Optional, Any, List, Tuple, Union import zhinst.utils from qcodes import Instrument @@ -102,41 +101,60 @@ def waveform_to_csv(self, wave_name: str, *waveforms: list) -> None: writer.writerows(zip(*waveforms)) @staticmethod - def generate_csv_sequence_program(wave_names: list, - channels: Optional[list] = None) -> str: + def generate_csv_sequence_program(wave_info: List[ + Tuple[int, Union[str, None], Union[str, None]]]) -> str: """ - Generates and returns a sequencing program that plays the given waves on - the given channels. There has to be a CSV file with a corresponding - name to a wave in wave_names. + A method that generates a sequence program that plays waveforms from + csv files. Args: - wave_names: List of wave names that are to be played. - channels: Channels to play the waveforms on. + wave_info: A list of tuples containing information about the waves + that are to be played. Every tuple should have a channel number and + wave, marker or both wave and marker. Returns: - A sequencing program that can be uploaded to the device. + A sequence program that can be compiled and uploaded. + """ awg_program = textwrap.dedent(""" - HEADER - while(true){ - playWave(WAVES); - } - """) + HEADER + DECLARATIONS + while(true){ + playWave(WAVES); + } + """) sequence_header = '// generated by {}\n'.format(__name__) awg_program = awg_program.replace('HEADER', sequence_header) - if channels is None: - argument_string = ('"{}"' * len(wave_names)).replace('""', '", "') - waves = argument_string.format(*wave_names) - else: - argument_string = ('{}, "{}"' * len(wave_names)).replace('}"{', - '}", {') - waves = argument_string.format( - *[value for pair in zip(channels, wave_names) for value in - pair]) - awg_program = awg_program.replace('WAVES', waves) - + declarations = ZIHDAWG8._generate_declarations(wave_info) + awg_program = awg_program.replace('DECLARATIONS', declarations) + play_wave_arguments = ZIHDAWG8._get_waveform_arguments(wave_info) + awg_program = awg_program.replace('WAVES', play_wave_arguments) return awg_program + @staticmethod + def _generate_declarations(wave_info): + declarations = "" + for _, wave, marker in wave_info: + if wave is not None and marker is not None: + declarations += ('wave {0} = "{0}";\n'.format(wave)) + declarations += ('wave {0} = "{0}";\n'.format(marker)) + declarations += ('{0} = {0} + {1};\n'.format(wave, marker)) + elif wave is not None: + declarations += ('wave {0} = "{0}";\n'.format(wave)) + elif marker is not None: + declarations += ('wave {0} = "{0}";\n'.format(marker)) + return declarations + + @staticmethod + def _get_waveform_arguments(wave_info): + argument_string = ('{}, {}' * len(wave_info)).replace('}{', '}, {') + play_wave_arguments = [] + for channel, wave, marker in wave_info: + play_wave_arguments.append(channel) + wave = wave if wave is not None else marker + play_wave_arguments.append(wave) + return argument_string.format(*play_wave_arguments) + def upload_sequence_program(self, awg_number: int, sequence_program: str) -> int: """ diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 73fd962754f..60c59489768 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -55,7 +55,8 @@ def setUp(self): }} def test_create_parameters_from_node_tree(self): - with patch.object(zhinst.utils, 'create_api_session', return_value=3 * (MagicMock(),)), \ + with patch.object(zhinst.utils, 'create_api_session', + return_value=3 * (MagicMock(),)), \ patch.object(ZIHDAWG8, 'download_device_node_tree', return_value=self.node_tree): hdawg8 = ZIHDAWG8('Name', 'dev-test') @@ -64,9 +65,11 @@ def test_create_parameters_from_node_tree(self): with self.assertRaises(ValueError): hdawg8.system_awg_channelgrouping.set(4) self.assertEqual('None', hdawg8.system_awg_channelgrouping.unit) - self.assertEqual('system_awg_channelgrouping', hdawg8.system_awg_channelgrouping.name) + self.assertEqual('system_awg_channelgrouping', + hdawg8.system_awg_channelgrouping.name) self.assertIsNotNone(hdawg8.system_awg_channelgrouping.vals) - self.assertIsInstance(hdawg8.system_awg_channelgrouping.vals, validators.Enum) + self.assertIsInstance(hdawg8.system_awg_channelgrouping.vals, + validators.Enum) self.assertIn('sigouts_0_on', hdawg8.parameters) self.assertEqual('None', hdawg8.sigouts_0_on.unit) @@ -80,54 +83,136 @@ def test_create_parameters_from_node_tree(self): self.assertIn('sines_0_amplitudes_0', hdawg8.parameters) self.assertEqual('None', hdawg8.sines_0_amplitudes_0.unit) - self.assertEqual('sines_0_amplitudes_0', hdawg8.sines_0_amplitudes_0.name) + self.assertEqual('sines_0_amplitudes_0', + hdawg8.sines_0_amplitudes_0.name) self.assertIsNone(hdawg8.sines_0_amplitudes_0.vals) self.assertIn('awgs_1_waveform_memoryusage', hdawg8.parameters) self.assertEqual('%', hdawg8.awgs_1_waveform_memoryusage.unit) - self.assertEqual('awgs_1_waveform_memoryusage', hdawg8.awgs_1_waveform_memoryusage.name) + self.assertEqual('awgs_1_waveform_memoryusage', + hdawg8.awgs_1_waveform_memoryusage.name) self.assertIsNone(hdawg8.awgs_1_waveform_memoryusage.vals) def test_generate_csv_sequence_program(self): expected = textwrap.dedent(""" // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 - + + wave wave_1 = "wave_1"; + wave wave_2 = "wave_2"; + wave wave_3 = "wave_3"; + while(true){ - playWave(1, "wave_1", 2, "wave_2", 3, "wave_3"); + playWave(1, wave_1, 2, wave_2, 3, wave_3); } """) - sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3'], [1, 2, 3]) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(1, 'wave_1', None), (2, 'wave_2', None), (3, 'wave_3', None)]) self.assertEqual(expected, sequence_program) - def test_generate_csv_sequence_program_no_channels(self): + def test_generate_csv_sequence_program_1_wave(self): expected = textwrap.dedent(""" // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 - + + wave wave_1 = "wave_1"; + while(true){ - playWave("wave_1", "wave_2", "wave_3"); + playWave(7, wave_1); } """) - sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1', 'wave_2', 'wave_3']) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(7, 'wave_1', None)]) self.assertEqual(expected, sequence_program) - def test_generate_csv_sequence_program_1_wave_no_channels(self): + def test_generate_csv_sequence_program_with_marker(self): expected = textwrap.dedent(""" // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 - + + wave wave_1 = "wave_1"; + wave marker_1 = "marker_1"; + wave_1 = wave_1 + marker_1; + while(true){ - playWave("wave_1"); + playWave(6, wave_1); } """) - sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1']) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(6, 'wave_1', "marker_1")]) self.assertEqual(expected, sequence_program) - def test_generate_csv_sequence_program_1_wave(self): + def test_generate_csv_sequence_program_with_marker_2_waves(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + wave wave_1 = "wave_1"; + wave marker_1 = "marker_1"; + wave_1 = wave_1 + marker_1; + wave wave_2 = "wave_2"; + + while(true){ + playWave(6, wave_1, 5, wave_2); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(6, 'wave_1', "marker_1"), (5, "wave_2", None)]) + self.assertEqual(expected, sequence_program) + + def test_generate_csv_sequence_program_with_marker_no_waves(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + wave marker_1 = "marker_1"; + + while(true){ + playWave(6, marker_1); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(6, None, "marker_1")]) + self.assertEqual(expected, sequence_program) + + def test_generate_csv_sequence_program_with_2_markers_1_wave(self): expected = textwrap.dedent(""" // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 - + + wave wave_1 = "wave_1"; + wave marker_1 = "marker_1"; + wave_1 = wave_1 + marker_1; + wave marker_2 = "marker_2"; + while(true){ - playWave(7, "wave_1"); + playWave(1, wave_1, 2, marker_2); } """) - sequence_program = ZIHDAWG8.generate_csv_sequence_program(['wave_1'], [7]) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(1, "wave_1", "marker_1"), (2, None, "marker_2")]) self.assertEqual(expected, sequence_program) + + def test_generate_large_csv_sequence_program(self): + expected = textwrap.dedent(""" + // generated by qcodes.instrument_drivers.ZI.ZIHDAWG8 + + wave wave_1 = "wave_1"; + wave marker_1 = "marker_1"; + wave_1 = wave_1 + marker_1; + wave marker_2 = "marker_2"; + wave marker_3 = "marker_3"; + wave wave_4 = "wave_4"; + wave wave_5 = "wave_5"; + wave marker_5 = "marker_5"; + wave_5 = wave_5 + marker_5; + wave wave_6 = "wave_6"; + wave wave_7 = "wave_7"; + wave marker_7 = "marker_7"; + wave_7 = wave_7 + marker_7; + wave marker_8 = "marker_8"; + + while(true){ + playWave(1, wave_1, 2, marker_2, 3, marker_3, 4, wave_4, 5, wave_5, 6, wave_6, 7, wave_7, 8, marker_8); + } + """) + sequence_program = ZIHDAWG8.generate_csv_sequence_program( + [(1, "wave_1", "marker_1"), (2, None, "marker_2"), + (3, None, "marker_3"), (4, "wave_4", None), + (5, "wave_5", "marker_5"), (6, "wave_6", None), + (7, "wave_7", "marker_7"), (8, None, "marker_8")]) + self.assertEqual(expected, sequence_program) \ No newline at end of file From a01531126ef3ec78c2751844dbd7afeb87908130 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 27 Nov 2018 11:06:47 +0100 Subject: [PATCH 228/719] Add explanatory notebook --- ...ing runs from one DB file to another.ipynb | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 docs/examples/DataSet/Extracting runs from one DB file to another.ipynb diff --git a/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb b/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb new file mode 100644 index 00000000000..56a164572cd --- /dev/null +++ b/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb @@ -0,0 +1,239 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Extracting runs from one DB file to another\n", + "\n", + "This notebook shows how to use the `extract_runs_into_db` function to extract runs from DB file (the source DB) into another DB file (the target DB). If the target DB does not exist, it will be created. The runs are **NOT** removed from the original DB file; they are copied over.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "Let us set up a DB file with some runs in it." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os \n", + "\n", + "import numpy as np\n", + "\n", + "from qcodes.dataset.sqlite_base import connect\n", + "from qcodes.dataset.database_extract_runs import extract_runs_into_db\n", + "from qcodes.dataset.experiment_container import new_experiment, load_experiment_by_name\n", + "from qcodes.tests.instrument_mocks import DummyInstrument\n", + "from qcodes.dataset.measurements import Measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "source_path = os.path.join(os.getcwd(), 'extract_runs_notebook_source.db')\n", + "target_path = os.path.join(os.getcwd(), 'extract_runs_notebook_target.db')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "source_conn = connect(source_path)\n", + "target_conn = connect(target_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "exp = new_experiment(name='extract_runs_experiment',\n", + " sample_name='no_sample',\n", + " conn=source_conn)\n", + "\n", + "my_inst = DummyInstrument('my_inst', gates=['voltage', 'current'])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 1\n", + "Starting experimental run with id: 2\n", + "Starting experimental run with id: 3\n", + "Starting experimental run with id: 4\n", + "Starting experimental run with id: 5\n", + "Starting experimental run with id: 6\n", + "Starting experimental run with id: 7\n", + "Starting experimental run with id: 8\n", + "Starting experimental run with id: 9\n", + "Starting experimental run with id: 10\n" + ] + } + ], + "source": [ + "meas = Measurement(exp=exp)\n", + "meas.register_parameter(my_inst.voltage)\n", + "meas.register_parameter(my_inst.current, setpoints=(my_inst.voltage,))\n", + "\n", + "#Add 10 runs with gradually more and more data\n", + "\n", + "for run_id in range(1, 11):\n", + " with meas.run() as datasaver:\n", + " for step, noise in enumerate(np.random.randn(run_id)):\n", + " datasaver.add_result((my_inst.voltage, step),\n", + " (my_inst.current, noise))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Extraction\n", + "\n", + "Now let us extract runs 3 and 7 into our desired target DB file. All runs must come from the same experiment. To extract runs from different experiments, call the function several times.\n", + "\n", + "The function will look in the target DB to see if an experiment with matching attributes already exists. If not, such an experiment is created." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "extract_runs_into_db(source_path, target_path, 3, 7)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "target_exp = load_experiment_by_name(name='extract_runs_experiment', conn=target_conn)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_exp.data_sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The last number printed in each line is the number of data points. As expected, we get 3 and 7.\n", + "\n", + "Note that the runs will have different `run_id`s in the new database. Their GUIDs are, however, the same (as they must be)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'aaaaaaaa-0c00-0007-0000-016754a23c83'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "exp.data_set(3).guid" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'aaaaaaaa-0c00-0007-0000-016754a23c83'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_exp.data_set(1).guid" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 726c1b527e64a6bfbd82eddce86ac5fea086fec1 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 27 Nov 2018 11:41:07 +0100 Subject: [PATCH 229/719] Make _fix_wrong_run_descriptions accept only ConnectionPlus --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 74c0e791318..706e20add1d 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -2150,7 +2150,7 @@ def remove_trigger(conn: SomeConnection, trigger_id: str) -> None: transaction(conn, f"DROP TRIGGER IF EXISTS {trigger_id};") -def _fix_wrong_run_descriptions(conn: SomeConnection, +def _fix_wrong_run_descriptions(conn: ConnectionPlus, run_ids: Sequence[int]) -> None: """ NB: This is a FIX function. Do not use it unless your database has been From 5660e8282b08e2f5c17c16393e940de1412fd679 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 27 Nov 2018 12:01:49 +0100 Subject: [PATCH 230/719] Get rid of SomeConnection in favor of ConnectionPlus everywhere --- qcodes/dataset/data_set.py | 4 +- qcodes/dataset/database.py | 4 +- qcodes/dataset/sqlite_base.py | 108 +++++++++++++++++----------------- 3 files changed, 57 insertions(+), 59 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index a8811d02d27..9fe296e6541 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -35,7 +35,7 @@ update_run_description, run_exists, remove_trigger, make_connection_plus_from, - SomeConnection) + ConnectionPlus) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -187,7 +187,7 @@ def _clean_up(self) -> None: class DataSet(Sized): def __init__(self, path_to_db: str=None, run_id: Optional[int]=None, - conn: Optional[SomeConnection]=None, + conn: Optional[ConnectionPlus]=None, exp_id=None, name: str=None, specs: SPECS=None, diff --git a/qcodes/dataset/database.py b/qcodes/dataset/database.py index 6ea49fdaacc..55d7971ab63 100644 --- a/qcodes/dataset/database.py +++ b/qcodes/dataset/database.py @@ -2,7 +2,7 @@ from os.path import expanduser -from qcodes.dataset.sqlite_base import SomeConnection +from qcodes.dataset.sqlite_base import ConnectionPlus from qcodes.dataset.sqlite_base import connect as _connect from qcodes.dataset.sqlite_base import init_db as _init_db import qcodes.config @@ -46,7 +46,7 @@ def initialise_or_create_database_at(db_file_with_abs_path: str) -> None: initialise_database() -def path_to_dbfile(conn: SomeConnection) -> str: +def path_to_dbfile(conn: ConnectionPlus) -> str: """ Return the path of the database file that the conn object is connected to """ diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 706e20add1d..5005f07b65e 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -132,9 +132,6 @@ def __init__(self, sqlite3_connection: sqlite3.Connection): '`ConnectionPlus` object which is not allowed.') -SomeConnection = Union[sqlite3.Connection, ConnectionPlus] - - def upgrader(func: Callable[[ConnectionPlus], None]): """ Decorator for database version upgrade functions. An upgrade function @@ -357,7 +354,7 @@ def connect(name: str, debug: bool = False, return conn -def perform_db_upgrade(conn: SomeConnection, version: int=-1) -> None: +def perform_db_upgrade(conn: ConnectionPlus, version: int=-1) -> None: """ This is intended to perform all upgrades as needed to bring the db from version 0 to the most current version (or the version specified). @@ -449,7 +446,7 @@ def perform_db_upgrade_1_to_2(conn: ConnectionPlus) -> None: raise RuntimeError(f"found {n_run_tables} runs tables expected 1") -def _2to3_get_result_tables(conn: SomeConnection) -> Dict[int, str]: +def _2to3_get_result_tables(conn: ConnectionPlus) -> Dict[int, str]: rst_query = "SELECT run_id, result_table_name FROM runs" cur = conn.cursor() cur.execute(rst_query) @@ -462,7 +459,7 @@ def _2to3_get_result_tables(conn: SomeConnection) -> Dict[int, str]: return results -def _2to3_get_layout_ids(conn: SomeConnection) -> DefaultDict[int, List[int]]: +def _2to3_get_layout_ids(conn: ConnectionPlus) -> DefaultDict[int, List[int]]: query = """ select runs.run_id, layouts.layout_id FROM layouts @@ -483,7 +480,7 @@ def _2to3_get_layout_ids(conn: SomeConnection) -> DefaultDict[int, List[int]]: return results -def _2to3_get_indeps(conn: SomeConnection) -> DefaultDict[int, List[int]]: +def _2to3_get_indeps(conn: ConnectionPlus) -> DefaultDict[int, List[int]]: query = """ SELECT layouts.run_id, layouts.layout_id FROM layouts @@ -504,7 +501,7 @@ def _2to3_get_indeps(conn: SomeConnection) -> DefaultDict[int, List[int]]: return results -def _2to3_get_deps(conn: SomeConnection) -> DefaultDict[int, List[int]]: +def _2to3_get_deps(conn: ConnectionPlus) -> DefaultDict[int, List[int]]: query = """ SELECT layouts.run_id, layouts.layout_id FROM layouts @@ -525,7 +522,7 @@ def _2to3_get_deps(conn: SomeConnection) -> DefaultDict[int, List[int]]: return results -def _2to3_get_dependencies(conn: SomeConnection) -> DefaultDict[int, List[int]]: +def _2to3_get_dependencies(conn: ConnectionPlus) -> DefaultDict[int, List[int]]: query = """ SELECT dependent, independent FROM dependencies @@ -548,7 +545,7 @@ def _2to3_get_dependencies(conn: SomeConnection) -> DefaultDict[int, List[int]]: return results -def _2to3_get_layouts(conn: SomeConnection) -> Dict[int, +def _2to3_get_layouts(conn: ConnectionPlus) -> Dict[int, Tuple[str, str, str, str]]: query = """ SELECT layout_id, parameter, label, unit, inferred_from @@ -566,7 +563,7 @@ def _2to3_get_layouts(conn: SomeConnection) -> Dict[int, return results -def _2to3_get_paramspecs(conn: SomeConnection, +def _2to3_get_paramspecs(conn: ConnectionPlus, layout_ids: List[int], layouts: Dict[int, Tuple[str, str, str, str]], dependencies: Dict[int, List[int]], @@ -701,7 +698,7 @@ def perform_db_upgrade_2_to_3(conn: ConnectionPlus) -> None: NEWEST_VERSION = len(UPGRADE_ACTIONS) -def transaction(conn: SomeConnection, +def transaction(conn: ConnectionPlus, sql: str, *args: Any) -> sqlite3.Cursor: """Perform a transaction. The transaction needs to be committed or rolled back. @@ -724,7 +721,7 @@ def transaction(conn: SomeConnection, return c -def atomic_transaction(conn: SomeConnection, +def atomic_transaction(conn: ConnectionPlus, sql: str, *args: Any) -> sqlite3.Cursor: """Perform an **atomic** transaction. The transaction is committed if there are no exceptions else the @@ -796,7 +793,8 @@ def atomic(conn: ConnectionPlus): conn.atomic_in_progress = old_atomic_in_progress -def make_connection_plus_from(conn: SomeConnection) -> ConnectionPlus: +def make_connection_plus_from(conn: Union[sqlite3.Connection, ConnectionPlus] + ) -> ConnectionPlus: """ Makes a ConnectionPlus connection object out of a given argument. @@ -804,7 +802,7 @@ def make_connection_plus_from(conn: SomeConnection) -> ConnectionPlus: without any changes. Args: - conn: an sqlite connection object as defined by SomeConnection type + conn: an sqlite database connection object Returns: the "same" connection but as ConnectionPlus object @@ -824,7 +822,7 @@ def init_db(conn: ConnectionPlus)->None: transaction(conn, _dependencies_table_schema) -def is_column_in_table(conn: SomeConnection, table: str, column: str) -> bool: +def is_column_in_table(conn: ConnectionPlus, table: str, column: str) -> bool: """ A look-before-you-leap function to look up if a table has a certain column. @@ -871,7 +869,7 @@ def insert_column(conn: ConnectionPlus, table: str, name: str, f'ALTER TABLE "{table}" ADD COLUMN "{name}"') -def select_one_where(conn: SomeConnection, table: str, column: str, +def select_one_where(conn: ConnectionPlus, table: str, column: str, where_column: str, where_value: Any) -> Any: query = f""" SELECT {column} @@ -885,7 +883,7 @@ def select_one_where(conn: SomeConnection, table: str, column: str, return res -def select_many_where(conn: SomeConnection, table: str, *columns: str, +def select_many_where(conn: ConnectionPlus, table: str, *columns: str, where_column: str, where_value: Any) -> Any: _columns = ",".join(columns) query = f""" @@ -912,7 +910,7 @@ def _massage_dict(metadata: Dict[str, Any]) -> Tuple[str, List[Any]]: return ','.join(template), values -def update_where(conn: SomeConnection, table: str, +def update_where(conn: ConnectionPlus, table: str, where_column: str, where_value: Any, **updates) -> None: _updates, values = _massage_dict(updates) query = f""" @@ -926,7 +924,7 @@ def update_where(conn: SomeConnection, table: str, atomic_transaction(conn, query, *values, where_value) -def insert_values(conn: SomeConnection, +def insert_values(conn: ConnectionPlus, formatted_name: str, columns: List[str], values: VALUES, @@ -1022,7 +1020,7 @@ def insert_many_values(conn: ConnectionPlus, return return_value -def modify_values(conn: SomeConnection, +def modify_values(conn: ConnectionPlus, formatted_name: str, index: int, columns: List[str], @@ -1049,7 +1047,7 @@ def modify_values(conn: SomeConnection, return c.rowcount -def modify_many_values(conn: SomeConnection, +def modify_many_values(conn: ConnectionPlus, formatted_name: str, start_index: int, columns: List[str], @@ -1075,7 +1073,7 @@ def modify_many_values(conn: SomeConnection, start_index += 1 -def length(conn: SomeConnection, +def length(conn: ConnectionPlus, formatted_name: str ) -> int: """ @@ -1097,7 +1095,7 @@ def length(conn: SomeConnection, return _len -def get_data(conn: SomeConnection, +def get_data(conn: ConnectionPlus, table_name: str, columns: List[str], start: Optional[int] = None, @@ -1141,7 +1139,7 @@ def get_data(conn: SomeConnection, return res -def get_values(conn: SomeConnection, +def get_values(conn: ConnectionPlus, table_name: str, param_name: str) -> List[List[Any]]: """ @@ -1165,7 +1163,7 @@ def get_values(conn: SomeConnection, return res -def get_setpoints(conn: SomeConnection, +def get_setpoints(conn: ConnectionPlus, table_name: str, param_name: str) -> Dict[str, List[List[Any]]]: """ @@ -1234,7 +1232,7 @@ def get_setpoints(conn: SomeConnection, return output -def get_layout(conn: SomeConnection, +def get_layout(conn: ConnectionPlus, layout_id) -> Dict[str, str]: """ Get the layout of a single parameter for plotting it @@ -1255,7 +1253,7 @@ def get_layout(conn: SomeConnection, return res -def get_layout_id(conn: SomeConnection, +def get_layout_id(conn: ConnectionPlus, parameter: Union[ParamSpec, str], run_id: int) -> int: """ @@ -1287,7 +1285,7 @@ def get_layout_id(conn: SomeConnection, return res -def get_dependents(conn: SomeConnection, +def get_dependents(conn: ConnectionPlus, run_id: int) -> List[int]: """ Get dependent layout_ids for a certain run_id, i.e. the layout_ids of all @@ -1302,7 +1300,7 @@ def get_dependents(conn: SomeConnection, return res -def get_dependencies(conn: SomeConnection, +def get_dependencies(conn: ConnectionPlus, layout_id: int) -> List[List[int]]: """ Get the dependencies of a certain dependent variable (indexed by its @@ -1322,7 +1320,7 @@ def get_dependencies(conn: SomeConnection, # Higher level Wrappers -def new_experiment(conn: SomeConnection, +def new_experiment(conn: ConnectionPlus, name: str, sample_name: str, format_string: Optional[str] = "{}-{}-{}" @@ -1351,7 +1349,7 @@ def new_experiment(conn: SomeConnection, # TODO(WilliamHPNielsen): we should remove the redundant # is_completed -def mark_run_complete(conn: SomeConnection, run_id: int): +def mark_run_complete(conn: ConnectionPlus, run_id: int): """ Mark run complete Args: @@ -1370,7 +1368,7 @@ def mark_run_complete(conn: SomeConnection, run_id: int): atomic_transaction(conn, query, time.time(), True, run_id) -def completed(conn: SomeConnection, run_id)->bool: +def completed(conn: ConnectionPlus, run_id)->bool: """ Check if the run scomplete Args: @@ -1382,7 +1380,7 @@ def completed(conn: SomeConnection, run_id)->bool: def get_completed_timestamp_from_run_id( - conn: SomeConnection, run_id: int) -> float: + conn: ConnectionPlus, run_id: int) -> float: """ Retrieve the timestamp when the given measurement run was completed @@ -1400,7 +1398,7 @@ def get_completed_timestamp_from_run_id( "run_id", run_id) -def get_guid_from_run_id(conn: SomeConnection, run_id: int) -> str: +def get_guid_from_run_id(conn: ConnectionPlus, run_id: int) -> str: """ Get the guid of the given run @@ -1411,7 +1409,7 @@ def get_guid_from_run_id(conn: SomeConnection, run_id: int) -> str: return select_one_where(conn, "runs", "guid", "run_id", run_id) -def finish_experiment(conn: SomeConnection, exp_id: int): +def finish_experiment(conn: ConnectionPlus, exp_id: int): """ Finish experiment Args: @@ -1424,7 +1422,7 @@ def finish_experiment(conn: SomeConnection, exp_id: int): atomic_transaction(conn, query, time.time(), exp_id) -def get_run_counter(conn: SomeConnection, exp_id: int) -> int: +def get_run_counter(conn: ConnectionPlus, exp_id: int) -> int: """ Get the experiment run counter Args: @@ -1440,7 +1438,7 @@ def get_run_counter(conn: SomeConnection, exp_id: int) -> int: where_value=exp_id) -def get_experiments(conn: SomeConnection) -> List[sqlite3.Row]: +def get_experiments(conn: ConnectionPlus) -> List[sqlite3.Row]: """ Get a list of experiments Args: conn: database connection @@ -1456,7 +1454,7 @@ def get_experiments(conn: SomeConnection) -> List[sqlite3.Row]: return c.fetchall() -def get_last_experiment(conn: SomeConnection) -> Optional[int]: +def get_last_experiment(conn: ConnectionPlus) -> Optional[int]: """ Return last started experiment id @@ -1493,7 +1491,7 @@ def get_runs(conn: ConnectionPlus, return c.fetchall() -def get_last_run(conn: SomeConnection, exp_id: int) -> Optional[int]: +def get_last_run(conn: ConnectionPlus, exp_id: int) -> Optional[int]: """ Get run_id of the last run in experiment with exp_id @@ -1514,7 +1512,7 @@ def get_last_run(conn: SomeConnection, exp_id: int) -> Optional[int]: return one(c, 'run_id') -def run_exists(conn: SomeConnection, run_id: int) -> bool: +def run_exists(conn: ConnectionPlus, run_id: int) -> bool: # the following query always returns a single sqlite3.Row with an integer # value of `1` or `0` for existing and non-existing run_id in the database query = """ @@ -1529,7 +1527,7 @@ def run_exists(conn: SomeConnection, run_id: int) -> bool: return bool(res[0]) -def data_sets(conn: SomeConnection) -> List[sqlite3.Row]: +def data_sets(conn: ConnectionPlus) -> List[sqlite3.Row]: """ Get a list of datasets Args: conn: database connection @@ -1620,7 +1618,7 @@ def _insert_run(conn: ConnectionPlus, exp_id: int, name: str, return run_counter, formatted_name, run_id -def _update_experiment_run_counter(conn: SomeConnection, exp_id: int, +def _update_experiment_run_counter(conn: ConnectionPlus, exp_id: int, run_counter: int) -> None: query = """ UPDATE experiments @@ -1630,7 +1628,7 @@ def _update_experiment_run_counter(conn: SomeConnection, exp_id: int, atomic_transaction(conn, query, run_counter, exp_id) -def get_parameters(conn: SomeConnection, +def get_parameters(conn: ConnectionPlus, run_id: int) -> List[ParamSpec]: """ Get the list of param specs for run @@ -1659,7 +1657,7 @@ def get_parameters(conn: SomeConnection, return parspecs -def get_paramspec(conn: SomeConnection, +def get_paramspec(conn: ConnectionPlus, run_id: int, param_name: str) -> ParamSpec: """ @@ -1933,14 +1931,14 @@ def create_run(conn: ConnectionPlus, exp_id: int, name: str, return run_counter, run_id, formatted_name -def get_metadata(conn: SomeConnection, tag: str, table_name: str): +def get_metadata(conn: ConnectionPlus, tag: str, table_name: str): """ Get metadata under the tag from table """ return select_one_where(conn, "runs", tag, "result_table_name", table_name) -def get_metadata_from_run_id(conn: SomeConnection, run_id: int) -> Dict: +def get_metadata_from_run_id(conn: ConnectionPlus, run_id: int) -> Dict: """ Get all metadata associated with the specified run """ @@ -1994,7 +1992,7 @@ def insert_meta_data(conn: ConnectionPlus, row_id: int, table_name: str, update_meta_data(conn, row_id, table_name, metadata) -def update_meta_data(conn: SomeConnection, row_id: int, table_name: str, +def update_meta_data(conn: ConnectionPlus, row_id: int, table_name: str, metadata: Dict[str, Any]) -> None: """ Updates metadata (they must exist already) @@ -2033,36 +2031,36 @@ def add_meta_data(conn: ConnectionPlus, raise e -def get_user_version(conn: SomeConnection) -> int: +def get_user_version(conn: ConnectionPlus) -> int: curr = atomic_transaction(conn, 'PRAGMA user_version') res = one(curr, 0) return res -def set_user_version(conn: SomeConnection, version: int) -> None: +def set_user_version(conn: ConnectionPlus, version: int) -> None: atomic_transaction(conn, 'PRAGMA user_version({})'.format(version)) def get_experiment_name_from_experiment_id( - conn: SomeConnection, exp_id: int) -> str: + conn: ConnectionPlus, exp_id: int) -> str: return select_one_where( conn, "experiments", "name", "exp_id", exp_id) def get_sample_name_from_experiment_id( - conn: SomeConnection, exp_id: int) -> str: + conn: ConnectionPlus, exp_id: int) -> str: return select_one_where( conn, "experiments", "sample_name", "exp_id", exp_id) -def get_run_timestamp_from_run_id(conn: SomeConnection, +def get_run_timestamp_from_run_id(conn: ConnectionPlus, run_id: int) -> float: return select_one_where(conn, "runs", "run_timestamp", "run_id", run_id) -def update_GUIDs(conn: SomeConnection) -> None: +def update_GUIDs(conn: ConnectionPlus) -> None: """ Update all GUIDs in this database where either the location code or the work_station code is zero to use the location and work_station code from @@ -2137,7 +2135,7 @@ def _both_zero(run_id: int, conn, guid_comps) -> None: actions[(loc == 0, ws == 0)](run_id, conn, guid_comps) -def remove_trigger(conn: SomeConnection, trigger_id: str) -> None: +def remove_trigger(conn: ConnectionPlus, trigger_id: str) -> None: """ Removes a trigger with a given id if it exists. From 9eefd792987adee477136147c0d19f1f4a5f71eb Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 27 Nov 2018 12:06:05 +0100 Subject: [PATCH 231/719] Skip database-file-dependent tests on file existence, not directory --- .../test_database_creation_and_upgrading.py | 30 +++++++++---------- qcodes/tests/dataset/test_database_fixes.py | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/qcodes/tests/dataset/test_database_creation_and_upgrading.py b/qcodes/tests/dataset/test_database_creation_and_upgrading.py index 1b651108b66..1a275d28a0c 100644 --- a/qcodes/tests/dataset/test_database_creation_and_upgrading.py +++ b/qcodes/tests/dataset/test_database_creation_and_upgrading.py @@ -136,12 +136,12 @@ def test_perform_actual_upgrade_0_to_1(): v0fixpath = os.path.join(fixturepath, 'db_files', 'version0') - if not os.path.exists(v0fixpath): + dbname_old = os.path.join(v0fixpath, 'empty.db') + + if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v0fixpath, 'empty.db') - with temporarily_copied_DB(dbname_old, debug=False, version=0) as conn: assert get_user_version(conn) == 0 @@ -164,12 +164,12 @@ def test_perform_actual_upgrade_1_to_2(): v1fixpath = os.path.join(fixturepath, 'db_files', 'version1') - if not os.path.exists(v1fixpath): + dbname_old = os.path.join(v1fixpath, 'empty.db') + + if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v1fixpath, 'empty.db') - with temporarily_copied_DB(dbname_old, debug=False, version=1) as conn: assert get_user_version(conn) == 1 @@ -194,12 +194,12 @@ def test_perform_actual_upgrade_2_to_3_empty(): v2fixpath = os.path.join(fixturepath, 'db_files', 'version2') - if not os.path.exists(v2fixpath): + dbname_old = os.path.join(v2fixpath, 'empty.db') + + if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v2fixpath, 'empty.db') - with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: assert get_user_version(conn) == 2 @@ -223,12 +223,12 @@ def test_perform_actual_upgrade_2_to_3_empty_runs(): v2fixpath = os.path.join(fixturepath, 'db_files', 'version2') - if not os.path.exists(v2fixpath): + dbname_old = os.path.join(v2fixpath, 'empty_runs.db') + + if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v2fixpath, 'empty_runs.db') - with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: perform_db_upgrade_2_to_3(conn) @@ -238,12 +238,12 @@ def test_perform_actual_upgrade_2_to_3_some_runs(): v2fixpath = os.path.join(fixturepath, 'db_files', 'version2') - if not os.path.exists(v2fixpath): + dbname_old = os.path.join(v2fixpath, 'some_runs.db') + + if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v2fixpath, 'some_runs.db') - with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: assert get_user_version(conn) == 2 diff --git a/qcodes/tests/dataset/test_database_fixes.py b/qcodes/tests/dataset/test_database_fixes.py index bea9ad33148..d82356c8566 100644 --- a/qcodes/tests/dataset/test_database_fixes.py +++ b/qcodes/tests/dataset/test_database_fixes.py @@ -17,13 +17,13 @@ def test_fix_wrong_run_descriptions(): v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') - if not os.path.exists(v3fixpath): + dbname_old = os.path.join(v3fixpath, 'some_runs_without_run_description.db') + + if not os.path.exists(dbname_old): pytest.skip( "No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") - dbname_old = os.path.join(v3fixpath, 'some_runs_without_run_description.db') - with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: assert get_user_version(conn) == 3 From 4ea67f9465beb161d283b2fffacfbc8f7ce98e30 Mon Sep 17 00:00:00 2001 From: GeneralSarsby Date: Tue, 27 Nov 2018 13:21:17 +0100 Subject: [PATCH 232/719] Update SR830.py included Tuple from the typing module. fixed the docstring indent. rearranged the section headings in the docstring. --- .../stanford_research/SR830.py | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 07859286b26..90baa867833 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -5,6 +5,8 @@ from qcodes.instrument.parameter import ArrayParameter from qcodes.utils.validators import Numbers, Ints, Enum, Strings +from typing import Tuple + class ChannelBuffer(ArrayParameter): """ @@ -492,42 +494,44 @@ def parse_offset_get(s): def snap(self, *parameters: str) -> Tuple[float, ...]: """ -Get between 2 and 6 parameters at a single instant. This provides a coherent -snapshot of measured signals. Pick up to 6 from: X, Y, R, θ, the aux -inputs 1-4, frequency, or what is currently displayed on channels 1 and 2. -Reading X and Y (or R and θ) gives a coherent snapshot of the signal. -Snap is important when the time constant is very short, a time constant less -than 100 ms. - -Args: - *parameters - From 2 to 6 strings of names of parameters for which the values are - requested. including: 'x', 'y', 'r', 'p', 'phase' or 'θ', - 'aux1', 'aux2', 'aux3', 'aux4', 'freq', 'ch1', and 'ch2'. - -Returns: - A tuple of floating point values in the same order as requested. - -Units: - Volts for x, y, r, and aux 1-4 - Degrees for θ - Hertz for freq - Unknown for ch1 and ch2. It will depend on what was set. - -Examples: - lockin.snap('x','y') -> tuple(x,y) - - lockin.snap('aux1','aux2','freq','phase') - -> tuple(aux1,aux2,freq,phase) - -Limitations: - - If X,Y,R and θ are all read, then the values of X,Y are recorded - approximately 10 µs apart from R,θ. Thus, the values of X and Y may not - yield the exact values of R and θ from a single snap. - - The values of the Aux Inputs may have an uncertainty of up to 32 µs. - - The frequency is computed only every other period or 40 ms, whichever is - longer. - """ + Get between 2 and 6 parameters at a single instant. This provides a + coherent snapshot of measured signals. Pick up to 6 from: X, Y, R, θ, + the aux inputs 1-4, frequency, or what is currently displayed on + channels 1 and 2. + + Reading X and Y (or R and θ) gives a coherent snapshot of the signal. + Snap is important when the time constant is very short, a time constant + less than 100 ms. + + Args: + *parameters + From 2 to 6 strings of names of parameters for which the values + are requested. including: 'x', 'y', 'r', 'p', 'phase' or 'θ', + 'aux1', 'aux2', 'aux3', 'aux4', 'freq', 'ch1', and 'ch2'. + + Returns: + A tuple of floating point values in the same order as requested. + + Examples: + lockin.snap('x','y') -> tuple(x,y) + + lockin.snap('aux1','aux2','freq','phase') + -> tuple(aux1,aux2,freq,phase) + + Note: + Volts for x, y, r, and aux 1-4 + Degrees for θ + Hertz for freq + Unknown for ch1 and ch2. It will depend on what was set. + + - If X,Y,R and θ are all read, then the values of X,Y are recorded + approximately 10 µs apart from R,θ. Thus, the values of X and Y + may not yield the exact values of R and θ from a single snap. + - The values of the Aux Inputs may have an uncertainty of + up to 32 µs. + - The frequency is computed only every other period or 40 ms, + whichever is longer. + """ if not 2 <= len(parameters) <= 6: raise KeyError( 'It is only possible to request values of 2 to 6 parameters' @@ -541,6 +545,7 @@ def snap(self, *parameters: str) -> Tuple[float, ...]: p_ids = [self.SNAP_PARAMETERS[name.lower()] for name in parameters] output = self.ask(f'SNAP? {",".join(p_ids)}') + return tuple(float(val) for val in output.split(',')) def _set_buffer_SR(self, SR): From 5b254854b7b811fa271b1dbc7b1975cb201c3894 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 27 Nov 2018 13:50:09 +0100 Subject: [PATCH 233/719] Add failing test for sample_name == None --- .../dataset/test_database_extract_runs.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 988083b41ae..9abe331d19d 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -423,3 +423,55 @@ def test_old_versions_not_touched(two_empty_temp_db_connections): 'upgrade_source_db=True to auto-upgrade ' 'the source DB file.') assert warning[0].message.args[0] == expected_mssg + + +def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections, + some_paramspecs): + """ + In older API versions (corresponding to DB version 3), + users could get away with setting the sample name to None + + This test checks that such an experiment gets correctly recognised and + is thus not ever re-inserted into the target DB + """ + source_conn, target_conn = two_empty_temp_db_connections + source_exp_1 = Experiment(conn=source_conn, name='null_sample_name') + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + # make 5 runs in experiment + + exp_1_run_ids = [] + for _ in range(5): + + source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id) + exp_1_run_ids.append(source_dataset.run_id) + + for ps in some_paramspecs[2].values(): + source_dataset.add_parameter(ps) + + for val in range(10): + source_dataset.add_result({ps.name: val + for ps in some_paramspecs[2].values()}) + source_dataset.mark_complete() + + sql = """ + UPDATE experiments + SET sample_name = NULL + WHERE exp_id = 1 + """ + source_conn.execute(sql) + source_conn.commit() + + assert source_exp_1.sample_name is None + + extract_runs_into_db(source_path, target_path, 1, 2, 3, 4, 5) + + assert len(get_experiments(target_conn)) == 1 + + extract_runs_into_db(source_path, target_path, 1, 2, 3, 4, 5) + + assert len(get_experiments(target_conn)) == 1 + + assert len(Experiment(exp_id=1, conn=target_conn)) == 5 From 08826741fee751ec7d79ed380416325a9ffcbc17 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Tue, 27 Nov 2018 13:56:18 +0100 Subject: [PATCH 234/719] Make experiments match on sample_name is None --- qcodes/dataset/sqlite_base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 39cb49ff17a..fadaa6a3de3 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1569,6 +1569,9 @@ def get_matching_exp_ids(conn: SomeConnection, **match_conditions) -> List: end_time = match_conditions.get('end_time', None) time_eq = "=" if end_time is not None else "IS" + sample_name = match_conditions.get('sample_name', None) + sample_name_eq = "=" if sample_name is not None else "IS" + query = "SELECT exp_id FROM experiments " for n, mcond in enumerate(match_conditions): if n == 0: @@ -1583,6 +1586,7 @@ def get_matching_exp_ids(conn: SomeConnection, **match_conditions) -> List: f'format_string = "{format_string}"') match_conditions.pop("format_string") query = query.replace("end_time = ?", f"end_time {time_eq} ?") + query = query.replace("sample_name = ?", f"sample_name {sample_name_eq} ?") cursor = conn.cursor() cursor.execute(query, tuple(match_conditions.values())) From 679c292af1e1c07d775f396d7dfe8e42b44a7f0f Mon Sep 17 00:00:00 2001 From: qSaevar Date: Tue, 27 Nov 2018 15:35:24 +0100 Subject: [PATCH 235/719] Override the snapshot_base method so all values are always up to date --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 8 +++++++- qcodes/tests/drivers/test_zihdawg8.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index 98fc94dfde1..d65fbd26c18 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -4,7 +4,7 @@ import textwrap import time from functools import partial -from typing import Optional, Any, List, Tuple, Union +from typing import Optional, Any, List, Tuple, Union, Sequence, Dict import zhinst.utils from qcodes import Instrument @@ -39,6 +39,12 @@ def __init__(self, name: str, device_id: str, **kwargs) -> None: node_tree = self.download_device_node_tree() self.create_parameters_from_node_tree(node_tree) + def snapshot_base(self, update: bool = False, + params_to_skip_update: Sequence[str] = None) -> Dict: + """ Override the base method to ensure all values are up-to-date""" + return super(ZIHDAWG8, self).snapshot_base(update=True, + params_to_skip_update=None) + def enable_channel(self, channel_number: int) -> None: """ Enable a signal output, turns on a blue LED on the device. diff --git a/qcodes/tests/drivers/test_zihdawg8.py b/qcodes/tests/drivers/test_zihdawg8.py index 60c59489768..bf4cc300e89 100644 --- a/qcodes/tests/drivers/test_zihdawg8.py +++ b/qcodes/tests/drivers/test_zihdawg8.py @@ -215,4 +215,4 @@ def test_generate_large_csv_sequence_program(self): (3, None, "marker_3"), (4, "wave_4", None), (5, "wave_5", "marker_5"), (6, "wave_6", None), (7, "wave_7", "marker_7"), (8, None, "marker_8")]) - self.assertEqual(expected, sequence_program) \ No newline at end of file + self.assertEqual(expected, sequence_program) From 6300a6133ac99a14808d1d1a0b4bcf7496b1de6b Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 27 Nov 2018 18:58:12 +0100 Subject: [PATCH 236/719] Use atomic for add_meta_data in DataSet instead of explicit commit --- qcodes/dataset/data_set.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 9fe296e6541..6396fd80399 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -478,9 +478,9 @@ def add_metadata(self, tag: str, metadata: Any): """ self._metadata[tag] = metadata - add_meta_data(self.conn, self.run_id, {tag: metadata}) - # `add_meta_data` does not commit, hence we commit here: - self.conn.commit() + # `add_meta_data` is not atomic by itself, hence using `atomic` + with atomic(self.conn) as conn: + add_meta_data(conn, self.run_id, {tag: metadata}) @property def started(self) -> bool: From cd28f708e35fdf040a7aa70d679bf30fdc438744 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 09:58:38 -0800 Subject: [PATCH 237/719] 1) more tests for better coverage 2) use re.sub to replace comma with period. --- qcodes/instrument_drivers/stahl/stahl.py | 57 +++++++++--------------- qcodes/tests/drivers/test_stahl.py | 37 ++++++++++++++- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index f0d4dec1bdd..2e224b095f2 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -2,11 +2,12 @@ This is a driver for the Stahl power supplies """ -from typing import Dict, Optional, Any, Callable, Union, Sequence +from typing import Dict, Optional, Any, Callable, Sequence import re import numpy as np import logging from collections import OrderedDict +from functools import partial from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Numbers @@ -31,7 +32,7 @@ def chain(*functions: Callable) -> Callable: Example: >>> def f(): - >>>> return "1.2" + >>> return "1.2" >>> chain(f, float)() # return 1.2 as float """ def make_tuple(args): @@ -73,7 +74,8 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): get_cmd=f"{self.parent.identifier} U{self._channel_string}", get_parser=chain( self.parent.regex_parser(r"([+\-]\d+,\d+) V$"), - self._string_to_float() + partial(re.sub, ",", "."), + float ), set_cmd=self._set_voltage, unit="V", @@ -88,9 +90,8 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): get_cmd=f"{self.parent.identifier} I{self._channel_string}", get_parser=chain( self.parent.regex_parser(r"([+\-]\d+,\d+) mA$"), - self._string_to_float( - scale_factor=1/1000 # We want results in Ampere - ) + partial(re.sub, ",", "."), + lambda ma: float(ma) / 1000 # Convert mA to A ), unit="A", ) @@ -100,22 +101,6 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): get_cmd=self._get_lock_status ) - @staticmethod - def _string_to_float( - decimal_separator: str=",", - scale_factor: float=1 - ) -> Callable: - """ - Querying the voltage and current gives back strings containing a - comma denoting a decimal separator (e.g. 1,4 = 1.4). Correct this - madness (and send an angry email to Stahl) - """ - def converter(string): - sane_str = string.replace(decimal_separator, ".") - return float(sane_str) * scale_factor - - return converter - def _set_voltage(self, voltage: float) -> None: """ Args: @@ -129,11 +114,13 @@ def _set_voltage(self, voltage: float) -> None: [0, 1] ) - send_string = f"{self.parent.identifier} CH{self._channel_string} {voltage_normalized:.5f}" + send_string = f"{self.parent.identifier} CH{self._channel_string} " \ + f"{voltage_normalized:.5f}" response = self.ask(send_string) if response != self.acknowledge_reply: - self.log.warning(f"Command {send_string} did not produce an acknowledge reply") + self.log.warning( + f"Command {send_string} did not produce an acknowledge reply") def _get_lock_status(self) -> bool: """ @@ -168,7 +155,7 @@ def __init__(self, name: str, address: str): super().__init__(name, address, terminator="\r") self.visa_handle.baud_rate = 115200 - instrument_info = self._parse_idn_string( + instrument_info = self.parse_idn_string( self.ask("IDN") ) @@ -205,8 +192,8 @@ def __init__(self, name: str, address: str): def ask_raw(self, cmd: str) -> str: """ - Sometimes the instrument returns non-ascii characters in response strings - Manually adjust the encoding to latin-1 + Sometimes the instrument returns non-ascii characters in response + strings manually adjust the encoding to latin-1 """ self.visa_log.debug(f"Querying: {cmd}") self.visa_handle.write(cmd) @@ -219,7 +206,7 @@ def regex_parser(match_string: str) -> Callable: """ Example: >>> parser = Stahl.regex_parser("^QCoDeS is (.*)$") - >>> result = parser("QCoDeS is Cool") # Will return 'Cool' + >>> result = parser("QCoDeS is Cool") # Will return ('Cool',) Raises: UnexpectedInstrumentResponse if a match could not be found with @@ -227,26 +214,22 @@ def regex_parser(match_string: str) -> Callable: """ regex = re.compile(match_string) - def parser(input_string: str) -> Union[str, Sequence[str]]: + def parser(input_string: str) -> Sequence[str]: result = regex.search(input_string) if result is None: raise UnexpectedInstrumentResponse() - result_groups = result.groups() - if len(result_groups) == 1: - return result_groups[0] - else: - return result_groups - + return result.groups() return parser - def _parse_idn_string(self, idn_string) -> Dict[str, Any]: + @staticmethod + def parse_idn_string(idn_string) -> Dict[str, Any]: """ Return: dict with keys: "model", "serial_number", "voltage_range", "n_channels", "output_type" """ - idn_parser = self.regex_parser( + idn_parser = Stahl.regex_parser( r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) ([buqsm])" ) parsed_idn = idn_parser(idn_string) diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py index e17246805db..f236b6d2b45 100644 --- a/qcodes/tests/drivers/test_stahl.py +++ b/qcodes/tests/drivers/test_stahl.py @@ -1,7 +1,11 @@ import pytest +import re +from functools import partial from qcodes.instrument_drivers.stahl import Stahl -from qcodes.instrument_drivers.stahl.stahl import UnexpectedInstrumentResponse, chain +from qcodes.instrument_drivers.stahl.stahl import ( + UnexpectedInstrumentResponse, chain +) def test_parse_simple(): @@ -11,7 +15,7 @@ def test_parse_simple(): response does not match the expectation """ parser = Stahl.regex_parser("^QCoDeS is (.*)$") - result = parser("QCoDeS is Cool") + result, = parser("QCoDeS is Cool") assert result == "Cool" with pytest.raises(UnexpectedInstrumentResponse): @@ -29,6 +33,24 @@ def test_parse_tuple(): assert b == "4" +def test_query_voltage_current(): + """ + Simulate Stahl weirdness when querying voltage or current. We do not simply + get a string representing a floating point value which we can convert by + casting to float. Instead, we need to use regular expressions. Additionally, + when querying voltage/current a comma instead of a period is used as the + decimal separator! Send an angry email to Stahl about this! + """ + parser = chain( + Stahl.regex_parser("channel 1 voltage: (.*)$"), + partial(re.sub, ",", "."), + float + ) + + answer = parser("channel 1 voltage: 2,3") + assert answer == 2.3 + + def test_chain(): """ Test chaining of callables @@ -44,3 +66,14 @@ def f(a, b): answer = parser("QCoDeS version is 3,4") assert answer == 7 + +def test_parse_idn_string(): + + idn_reply = "BS123 005 16 b" + assert Stahl.parse_idn_string(idn_reply) == { + "model": "BS", + "serial_number": "123", + "voltage_range": 5.0, + "n_channels": 16, + "output_type": "bipolar" + } From 3522387445ec93b0c0fa6aec4471d7f143bf697c Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Tue, 27 Nov 2018 19:00:27 +0100 Subject: [PATCH 238/719] Ignore versioned .db files that are generated for some tests --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index fa1da1dcef9..616fe3dde34 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,6 @@ experiments.db benchmarking/env/ benchmarking/html/ benchmarking/results/ + +# Ignore .db files that are generated for some tests +qcodes/tests/dataset/fixtures/db_files/* From ef0dc30ee1d61abd93454b7d5780fb92e44f8f3e Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 15:49:12 -0800 Subject: [PATCH 239/719] added stahl simulator and added more tests to improve coverage --- .../Qcodes example with Stahl.ipynb | 267 +++++++++++++++++- qcodes/instrument/sims/stahl.yaml | 43 +++ qcodes/instrument_drivers/stahl/stahl.py | 21 +- qcodes/tests/drivers/test_stahl.py | 94 +++++- 4 files changed, 397 insertions(+), 28 deletions(-) create mode 100644 qcodes/instrument/sims/stahl.yaml diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index d279f493e00..c632c10ce0e 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -27,7 +27,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Stahl HV (serial:171, firmware:None) in 0.06s\n" + "Connected to: Stahl HV (serial:171, firmware:None) in 0.19s\n" ] } ], @@ -44,7 +44,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.001\n" + "2.002\n" ] } ], @@ -100,7 +100,7 @@ { "data": { "text/plain": [ - "2e-06" + "1e-06" ] }, "execution_count": 6, @@ -192,6 +192,267 @@ "stahl.output_type" ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\x06'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chr(6)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging \n", + "import io" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "iostream = io.StringIO()\n", + "logger = logging.getLogger()\n", + "logger.setLevel(logging.DEBUG)\n", + "lh = logging.StreamHandler(iostream)\n", + "logger.addHandler(lh)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "logger.debug(\"some warning\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'some warning\\n'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "iostream.getvalue()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__class__',\n", + " '__delattr__',\n", + " '__dict__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__eq__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__le__',\n", + " '__lt__',\n", + " '__module__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__setattr__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " '__weakref__',\n", + " '_name',\n", + " 'acquire',\n", + " 'addFilter',\n", + " 'close',\n", + " 'createLock',\n", + " 'emit',\n", + " 'filter',\n", + " 'filters',\n", + " 'flush',\n", + " 'format',\n", + " 'formatter',\n", + " 'get_name',\n", + " 'handle',\n", + " 'handleError',\n", + " 'level',\n", + " 'lock',\n", + " 'name',\n", + " 'release',\n", + " 'removeFilter',\n", + " 'setFormatter',\n", + " 'setLevel',\n", + " 'set_name',\n", + " 'stream',\n", + " 'terminator']" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(logger.handlers[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'some warning\\n'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "logger.handlers[0].stream.getvalue()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "176" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ord(\"°\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0b10110000'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bin(176)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'°'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(\"°\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0xb0'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hex(176)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'°'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(\"\\xb0\")" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument/sims/stahl.yaml b/qcodes/instrument/sims/stahl.yaml new file mode 100644 index 00000000000..2bd71135052 --- /dev/null +++ b/qcodes/instrument/sims/stahl.yaml @@ -0,0 +1,43 @@ +spec: "1.0" +devices: + device 1: + eom: + ASRL INSTR: + q: "\r" + r: "\r" + error: ERROR + dialogues: + - q: "IDN" + r: "BS123 005 16 b" + + properties: + voltage_ch1: + default: 1.2 + getter: + q: "BS123 U01" + r: "-1,2 V" + setter: + q: "BS123 CH01 {}" + r: "\x06" + voltage_ch2: + default: 1.2 + getter: + q: "BS123 U02" + r: "-1,2 V" + setter: + q: "BS123 CH02 {}" + r: "" + current_ch1: + default: 0.001 + getter: + q: "BS123 I01" + r: "+0,001 mA" + temperature: + getter: + q: "BS123 TEMP" + r: "TEMP 27\xb0C" + + +resources: + "ASRL3": + device: device 1 diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 2e224b095f2..407b9000044 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -16,16 +16,6 @@ logger = logging.getLogger() -class UnexpectedInstrumentResponse(Exception): - def __init__(self): - super().__init__( - "Unexpected instrument response. Perhaps the model of the " - "instrument does not match the drivers expectation or a " - "firmware upgrade has taken place. Please get in touch " - "with a QCoDeS core developer" - ) - - def chain(*functions: Callable) -> Callable: """ The output of the first callable is piped to the input of the second, etc. @@ -151,8 +141,8 @@ class Stahl(VisaInstrument): name address: A serial port address """ - def __init__(self, name: str, address: str): - super().__init__(name, address, terminator="\r") + def __init__(self, name: str, address: str, **kwargs): + super().__init__(name, address, terminator="\r", **kwargs) self.visa_handle.baud_rate = 115200 instrument_info = self.parse_idn_string( @@ -217,7 +207,12 @@ def regex_parser(match_string: str) -> Callable: def parser(input_string: str) -> Sequence[str]: result = regex.search(input_string) if result is None: - raise UnexpectedInstrumentResponse() + raise RuntimeError( + "Unexpected instrument response. Perhaps the model of the " + "instrument does not match the drivers expectation or a " + "firmware upgrade has taken place. Please get in touch " + "with a QCoDeS core developer" + ) return result.groups() return parser diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py index f236b6d2b45..c08186c3fe7 100644 --- a/qcodes/tests/drivers/test_stahl.py +++ b/qcodes/tests/drivers/test_stahl.py @@ -1,11 +1,31 @@ import pytest import re from functools import partial +import logging +import io from qcodes.instrument_drivers.stahl import Stahl -from qcodes.instrument_drivers.stahl.stahl import ( - UnexpectedInstrumentResponse, chain -) +from qcodes.instrument_drivers.stahl.stahl import chain +import qcodes.instrument.sims as sims + + +@pytest.fixture(scope="function") +def stahl_instrument(): + visa_lib = sims.__file__.replace( + '__init__.py', + 'stahl.yaml@sim' + ) + + inst = Stahl('Stahl', 'ASRL3', visalib=visa_lib) + inst.log.setLevel(logging.DEBUG) + iostream = io.StringIO() + lh = logging.StreamHandler(iostream) + inst.log.logger.addHandler(lh) + + try: + yield inst + finally: + inst.close() def test_parse_simple(): @@ -18,7 +38,10 @@ def test_parse_simple(): result, = parser("QCoDeS is Cool") assert result == "Cool" - with pytest.raises(UnexpectedInstrumentResponse): + with pytest.raises( + RuntimeError, + match=r"Unexpected instrument response" + ): parser("QCoDe is Cool") @@ -67,13 +90,60 @@ def f(a, b): assert answer == 7 -def test_parse_idn_string(): - - idn_reply = "BS123 005 16 b" - assert Stahl.parse_idn_string(idn_reply) == { +def test_parse_idn_string(stahl_instrument): + """ + 1) Assert that the correct IDN message is received and parsed + 2) Instrument attributes are set correctly + """ + assert stahl_instrument.IDN() == { + "vendor": "Stahl", "model": "BS", - "serial_number": "123", - "voltage_range": 5.0, - "n_channels": 16, - "output_type": "bipolar" + "serial": "123", + "firmware": None } + + assert stahl_instrument.n_channels == 16 + assert stahl_instrument.voltage_range == 5.0 + assert stahl_instrument.output_type == "bipolar" + + +def test_get_set_voltage(stahl_instrument): + """ + Test that we can correctly get/set voltages + """ + stahl_instrument.channel[0].voltage(1.2) + assert stahl_instrument.channel[0].voltage() == -1.2 + logger = stahl_instrument.log.logger + log_messages = logger.handlers[0].stream.getvalue() + assert "did not produce an acknowledge reply" not in log_messages + + +def test_get_set_voltage_assert_warning(stahl_instrument): + """ + On channel 2 we have deliberately introduced an error in the + visa simulation; setting a voltage does not produce an acknowledge + string. Test that a warning is correctly issued. + """ + stahl_instrument.channel[1].voltage(1.0) + logger = stahl_instrument.log.logger + log_messages = logger.handlers[0].stream.getvalue() + assert "did not produce an acknowledge reply" in log_messages + + +def test_get_current(stahl_instrument): + """ + Test that we can read currents and that the unit is in Ampere + """ + assert stahl_instrument.channel[0].current() == 1E-6 + assert stahl_instrument.channel[0].current.unit == "A" + + +def test_get_temperature(stahl_instrument): + """ + Due to limitations in pyvisa-sim, we cannot test this. + Line 191 of pyvisa-sim\component.py should read + "return response.encode('latin-1')" for this to work. + """ + pass + + From 75408f251bace9c9dc3034d6caa16f03ee6d4d4f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 15:52:13 -0800 Subject: [PATCH 240/719] clean up notebook --- .../Qcodes example with Stahl.ipynb | 261 ------------------ 1 file changed, 261 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb index c632c10ce0e..9ac6e14a42a 100644 --- a/docs/examples/driver_examples/Qcodes example with Stahl.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Stahl.ipynb @@ -192,267 +192,6 @@ "stahl.output_type" ] }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'\\x06'" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chr(6)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging \n", - "import io" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "iostream = io.StringIO()\n", - "logger = logging.getLogger()\n", - "logger.setLevel(logging.DEBUG)\n", - "lh = logging.StreamHandler(iostream)\n", - "logger.addHandler(lh)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "logger.debug(\"some warning\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'some warning\\n'" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iostream.getvalue()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['__class__',\n", - " '__delattr__',\n", - " '__dict__',\n", - " '__dir__',\n", - " '__doc__',\n", - " '__eq__',\n", - " '__format__',\n", - " '__ge__',\n", - " '__getattribute__',\n", - " '__gt__',\n", - " '__hash__',\n", - " '__init__',\n", - " '__init_subclass__',\n", - " '__le__',\n", - " '__lt__',\n", - " '__module__',\n", - " '__ne__',\n", - " '__new__',\n", - " '__reduce__',\n", - " '__reduce_ex__',\n", - " '__repr__',\n", - " '__setattr__',\n", - " '__sizeof__',\n", - " '__str__',\n", - " '__subclasshook__',\n", - " '__weakref__',\n", - " '_name',\n", - " 'acquire',\n", - " 'addFilter',\n", - " 'close',\n", - " 'createLock',\n", - " 'emit',\n", - " 'filter',\n", - " 'filters',\n", - " 'flush',\n", - " 'format',\n", - " 'formatter',\n", - " 'get_name',\n", - " 'handle',\n", - " 'handleError',\n", - " 'level',\n", - " 'lock',\n", - " 'name',\n", - " 'release',\n", - " 'removeFilter',\n", - " 'setFormatter',\n", - " 'setLevel',\n", - " 'set_name',\n", - " 'stream',\n", - " 'terminator']" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dir(logger.handlers[0])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'some warning\\n'" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "logger.handlers[0].stream.getvalue()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "176" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord(\"°\")" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0b10110000'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bin(176)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'°'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(\"°\")" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'0xb0'" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hex(176)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'°'" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(\"\\xb0\")" - ] - }, { "cell_type": "code", "execution_count": null, From a3c9c2e2f8d4388dba892e7d8217afd7e5acd9e8 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 15:55:34 -0800 Subject: [PATCH 241/719] 1) Docstring in regex_parser: raises runtimerror 2) extra newlines removal in test --- qcodes/instrument_drivers/stahl/stahl.py | 2 +- qcodes/tests/drivers/test_stahl.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 407b9000044..fece0b26fa0 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -199,7 +199,7 @@ def regex_parser(match_string: str) -> Callable: >>> result = parser("QCoDeS is Cool") # Will return ('Cool',) Raises: - UnexpectedInstrumentResponse if a match could not be found with + RuntimeError if a match could not be found with regular expressions """ regex = re.compile(match_string) diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py index c08186c3fe7..02baa1a90b3 100644 --- a/qcodes/tests/drivers/test_stahl.py +++ b/qcodes/tests/drivers/test_stahl.py @@ -145,5 +145,3 @@ def test_get_temperature(stahl_instrument): "return response.encode('latin-1')" for this to work. """ pass - - From dd0fdb8e145c03a31f9b41258381351628418120 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 17:21:07 -0800 Subject: [PATCH 242/719] initial commit --- .../tektronix/Keithley_s46.py | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 qcodes/instrument_drivers/tektronix/Keithley_s46.py diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py new file mode 100644 index 00000000000..e578ca9309a --- /dev/null +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -0,0 +1,105 @@ +import numpy as np +import itertools +from collections import defaultdict + +from qcodes import VisaInstrument, InstrumentChannel, ChannelList + + +class RelayLock: + def __init__(self): + self.acquired = False + self.acquired_by = None + + def acquire(self, requester_id): + if self.acquired and self.acquired_by != requester_id: + raise RuntimeError( + "Relay {self.name} already in use by another channel on the " + "same relay" + ) + + self.acquired = True + self.acquired_by = requester_id + + def release(self, requester_id): + if self.acquired_by != requester_id: + raise RuntimeError( + "Relay can only be freed by the channel that acquired the lock") + + self.acquired = False + self.acquired_by = None + + +class ChannelNotPresentError(Exception): + pass + + +class RFSwitchChannel(InstrumentChannel): + def __init__(self, parent, name, channel_number, relay_locks): + super().__init__(parent, name) + self._channel_number = channel_number + + relay_id = self._get_relay() + self._relay_lock = relay_locks[relay_id] + + self.add_parameter( + "is_closed", + get_cmd=lambda: self._channel_number in + self.parent.query_closed_channels() + ) + + def _get_relay(self): + relay_layout = self.parent.get_relay_layout() + found = False + + count = 0 + for count, total_count in enumerate(np.cumsum(relay_layout)): + if total_count >= self._channel_number: + found = True + break + + if not found: + raise ChannelNotPresentError() + + return ["A", "B", "C", "D", "1", "2", "3", "4", "5", "6", "7", "8"][ + count] + + def close_channel(self): + self._relay_lock.acquire(self._channel_number) + self.write(f":CLOSE (@{self._channel_number})") + + def open_channel(self): + self._relay_lock.release(self._channel_number) + self.write(f":OPEN (@{self._channel_number})") + + +class S46(VisaInstrument): + def __init__(self, name, address, **kwargs): + super().__init__(name, address, terminator="\n", **kwargs) + + channels = ChannelList( + self, "channel", RFSwitchChannel, snapshotable=False + ) + + relay_locks = defaultdict(RelayLock) + + for chn in itertools.count(1): + chn_name = f"channel{chn}" + + try: + channel = RFSwitchChannel(self, chn_name, chn, relay_locks) + except ChannelNotPresentError: + break + + self.add_submodule(chn_name, channel) + channels.append(channel) + + self.add_submodule("channels", channels) + self.connect_message() + + def query_closed_channels(self): + response = self.ask(":CLOS?") + channels_list_string = response.lstrip("(@").rstrip(")") + return [int(i) for i in channels_list_string.split(",")] + + def get_relay_layout(self): + return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] \ No newline at end of file From 72a554e26bd1ef2ae25136beab3f1845fb66ada9 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 27 Nov 2018 18:32:49 -0800 Subject: [PATCH 243/719] initial commit --- .../tektronix/Keithley_s46.py | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index e578ca9309a..9116c3ee7e3 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -5,6 +5,10 @@ from qcodes import VisaInstrument, InstrumentChannel, ChannelList +class ChannelNotPresentError(Exception): + pass + + class RelayLock: def __init__(self): self.acquired = False @@ -13,8 +17,7 @@ def __init__(self): def acquire(self, requester_id): if self.acquired and self.acquired_by != requester_id: raise RuntimeError( - "Relay {self.name} already in use by another channel on the " - "same relay" + f"Relay already in use by channel {self.acquired_by}" ) self.acquired = True @@ -23,32 +26,33 @@ def acquire(self, requester_id): def release(self, requester_id): if self.acquired_by != requester_id: raise RuntimeError( - "Relay can only be freed by the channel that acquired the lock") + f"Relay can only be freed by channel {self.acquired_by} " + f"that acquired the lock" + ) self.acquired = False self.acquired_by = None -class ChannelNotPresentError(Exception): - pass - - class RFSwitchChannel(InstrumentChannel): def __init__(self, parent, name, channel_number, relay_locks): super().__init__(parent, name) self._channel_number = channel_number - relay_id = self._get_relay() - self._relay_lock = relay_locks[relay_id] + self._relay_id = self._get_relay() + self._relay_lock = relay_locks[self._relay_id] self.add_parameter( - "is_closed", - get_cmd=lambda: self._channel_number in - self.parent.query_closed_channels() + "close", + get_cmd=lambda: str(self._channel_number) in self.ask(":CONF:CPOL?"), + set_cmd=lambda state: { + True: self._close_channel, + False: self._open_channel + }[state]() ) def _get_relay(self): - relay_layout = self.parent.get_relay_layout() + relay_layout = self.parent.relay_layout() found = False count = 0 @@ -60,22 +64,29 @@ def _get_relay(self): if not found: raise ChannelNotPresentError() - return ["A", "B", "C", "D", "1", "2", "3", "4", "5", "6", "7", "8"][ - count] + return (["A", "B", "C", "D"] + [chr(i) for i in range(1, 9)])[count] - def close_channel(self): + def _close_channel(self): self._relay_lock.acquire(self._channel_number) self.write(f":CLOSE (@{self._channel_number})") - def open_channel(self): + def _open_channel(self): self._relay_lock.release(self._channel_number) self.write(f":OPEN (@{self._channel_number})") + @property + def relay_id(self): + return self._relay_id + class S46(VisaInstrument): def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) + self._relay_layout = [ + int(i) for i in self.ask(":CONF:CPOL?").split(",") + ] + channels = ChannelList( self, "channel", RFSwitchChannel, snapshotable=False ) @@ -96,10 +107,6 @@ def __init__(self, name, address, **kwargs): self.add_submodule("channels", channels) self.connect_message() - def query_closed_channels(self): - response = self.ask(":CLOS?") - channels_list_string = response.lstrip("(@").rstrip(")") - return [int(i) for i in channels_list_string.split(",")] - - def get_relay_layout(self): - return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] \ No newline at end of file + @property + def relay_layout(self): + return self._relay_layout From 447afaa8b5deb0a421135b3ccebe77fcd6e97747 Mon Sep 17 00:00:00 2001 From: sohailc Date: Tue, 27 Nov 2018 23:26:50 -0800 Subject: [PATCH 244/719] get rid of regex_parser --- qcodes/instrument_drivers/stahl/stahl.py | 61 +++++++------------ qcodes/tests/drivers/test_stahl.py | 75 +++++------------------- 2 files changed, 36 insertions(+), 100 deletions(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index fece0b26fa0..7783d2d9ab6 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -2,7 +2,7 @@ This is a driver for the Stahl power supplies """ -from typing import Dict, Optional, Any, Callable, Sequence +from typing import Dict, Optional, Any, Callable, Sequence, Iterable import re import numpy as np import logging @@ -12,7 +12,6 @@ from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Numbers - logger = logging.getLogger() @@ -25,15 +24,16 @@ def chain(*functions: Callable) -> Callable: >>> return "1.2" >>> chain(f, float)() # return 1.2 as float """ - def make_tuple(args): - if not isinstance(args, tuple): + + def make_iter(args): + if not isinstance(args, Iterable) or isinstance(args, str): return args, return args def inner(*args): result = args for fun in functions: - new_args = make_tuple(result) + new_args = make_iter(result) result = fun(*new_args) return result @@ -63,7 +63,7 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): "voltage", get_cmd=f"{self.parent.identifier} U{self._channel_string}", get_parser=chain( - self.parent.regex_parser(r"([+\-]\d+,\d+) V$"), + re.compile(r"^([+\-]\d+,\d+) V$").findall, partial(re.sub, ",", "."), float ), @@ -79,7 +79,7 @@ def __init__(self, parent: VisaInstrument, name: str, channel_number: int): "current", get_cmd=f"{self.parent.identifier} I{self._channel_string}", get_parser=chain( - self.parent.regex_parser(r"([+\-]\d+,\d+) mA$"), + re.compile(r"^([+\-]\d+,\d+) mA$").findall, partial(re.sub, ",", "."), lambda ma: float(ma) / 1000 # Convert mA to A ), @@ -105,7 +105,7 @@ def _set_voltage(self, voltage: float) -> None: ) send_string = f"{self.parent.identifier} CH{self._channel_string} " \ - f"{voltage_normalized:.5f}" + f"{voltage_normalized:.5f}" response = self.ask(send_string) if response != self.acknowledge_reply: @@ -141,6 +141,7 @@ class Stahl(VisaInstrument): name address: A serial port address """ + def __init__(self, name: str, address: str, **kwargs): super().__init__(name, address, terminator="\r", **kwargs) self.visa_handle.baud_rate = 115200 @@ -172,7 +173,7 @@ def __init__(self, name: str, address: str, **kwargs): "temperature", get_cmd=f"{self.identifier} TEMP", get_parser=chain( - self.regex_parser("TEMP (.*)°C"), + re.compile("^TEMP (.*)°C$").findall, float ), unit="C" @@ -191,32 +192,6 @@ def ask_raw(self, cmd: str) -> str: self.visa_log.debug(f"Response: {response}") return response - @staticmethod - def regex_parser(match_string: str) -> Callable: - """ - Example: - >>> parser = Stahl.regex_parser("^QCoDeS is (.*)$") - >>> result = parser("QCoDeS is Cool") # Will return ('Cool',) - - Raises: - RuntimeError if a match could not be found with - regular expressions - """ - regex = re.compile(match_string) - - def parser(input_string: str) -> Sequence[str]: - result = regex.search(input_string) - if result is None: - raise RuntimeError( - "Unexpected instrument response. Perhaps the model of the " - "instrument does not match the drivers expectation or a " - "firmware upgrade has taken place. Please get in touch " - "with a QCoDeS core developer" - ) - - return result.groups() - return parser - @staticmethod def parse_idn_string(idn_string) -> Dict[str, Any]: """ @@ -224,10 +199,18 @@ def parse_idn_string(idn_string) -> Dict[str, Any]: dict with keys: "model", "serial_number", "voltage_range", "n_channels", "output_type" """ - idn_parser = Stahl.regex_parser( - r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) ([buqsm])" + result = re.search( + r"(HV|BS)(\d{3}) (\d{3}) (\d{2}) ([buqsm])", + idn_string ) - parsed_idn = idn_parser(idn_string) + + if result is None: + raise RuntimeError( + "Unexpected instrument response. Perhaps the model of the " + "instrument does not match the drivers expectation or a " + "firmware upgrade has taken place. Please get in touch " + "with a QCoDeS core developer" + ) converters: Dict[str, Callable] = OrderedDict({ "model": str, @@ -245,7 +228,7 @@ def parse_idn_string(idn_string) -> Dict[str, Any]: return { name: converter(value) - for (name, converter), value in zip(converters.items(), parsed_idn) + for (name, converter), value in zip(converters.items(), result.groups()) } def get_idn(self) -> Dict[str, Optional[str]]: diff --git a/qcodes/tests/drivers/test_stahl.py b/qcodes/tests/drivers/test_stahl.py index 02baa1a90b3..1a3ffc11136 100644 --- a/qcodes/tests/drivers/test_stahl.py +++ b/qcodes/tests/drivers/test_stahl.py @@ -1,11 +1,8 @@ import pytest -import re -from functools import partial import logging import io from qcodes.instrument_drivers.stahl import Stahl -from qcodes.instrument_drivers.stahl.stahl import chain import qcodes.instrument.sims as sims @@ -28,72 +25,28 @@ def stahl_instrument(): inst.close() -def test_parse_simple(): +def test_parse_idn_string(): """ - Test that we can parse simple messages from the instrument - and that the proper exception is raised when the received - response does not match the expectation + Test that we can parse IDN strings correctly """ - parser = Stahl.regex_parser("^QCoDeS is (.*)$") - result, = parser("QCoDeS is Cool") - assert result == "Cool" + assert Stahl.parse_idn_string("HV123 005 16 b") == { + "model": "HV", + "serial_number": "123", + "voltage_range": 5.0, + "n_channels": 16, + "output_type": "bipolar" + } with pytest.raises( RuntimeError, - match=r"Unexpected instrument response" + match="Unexpected instrument response" ): - parser("QCoDe is Cool") - - -def test_parse_tuple(): - """ - Test that we can extract multiple values from a string - """ - parser = Stahl.regex_parser(r"^QCoDeS version is (\d),(\d)$") - a, b = parser("QCoDeS version is 3,4") - - assert a == "3" - assert b == "4" - - -def test_query_voltage_current(): - """ - Simulate Stahl weirdness when querying voltage or current. We do not simply - get a string representing a floating point value which we can convert by - casting to float. Instead, we need to use regular expressions. Additionally, - when querying voltage/current a comma instead of a period is used as the - decimal separator! Send an angry email to Stahl about this! - """ - parser = chain( - Stahl.regex_parser("channel 1 voltage: (.*)$"), - partial(re.sub, ",", "."), - float - ) - - answer = parser("channel 1 voltage: 2,3") - assert answer == 2.3 - - -def test_chain(): - """ - Test chaining of callables - """ - def f(a, b): - return int(a) + int(b) - - parser = chain( - Stahl.regex_parser(r"^QCoDeS version is (\d),(\d)$"), - f - ) - - answer = parser("QCoDeS version is 3,4") - assert answer == 7 + Stahl.parse_idn_string("HS123 005 16 bla b") -def test_parse_idn_string(stahl_instrument): +def test_get_idn(stahl_instrument): """ - 1) Assert that the correct IDN message is received and parsed - 2) Instrument attributes are set correctly + Instrument attributes are set correctly after getting the IDN """ assert stahl_instrument.IDN() == { "vendor": "Stahl", @@ -141,7 +94,7 @@ def test_get_current(stahl_instrument): def test_get_temperature(stahl_instrument): """ Due to limitations in pyvisa-sim, we cannot test this. - Line 191 of pyvisa-sim\component.py should read + Line 191 of pyvisa-sim/component.py should read "return response.encode('latin-1')" for this to work. """ pass From b4eb7184f64d8b10b4c301022f555bccedda3d22 Mon Sep 17 00:00:00 2001 From: sohailc Date: Wed, 28 Nov 2018 00:20:47 -0800 Subject: [PATCH 245/719] remove unused import --- qcodes/instrument_drivers/stahl/stahl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stahl/stahl.py b/qcodes/instrument_drivers/stahl/stahl.py index 7783d2d9ab6..ba26191dcf1 100644 --- a/qcodes/instrument_drivers/stahl/stahl.py +++ b/qcodes/instrument_drivers/stahl/stahl.py @@ -2,7 +2,7 @@ This is a driver for the Stahl power supplies """ -from typing import Dict, Optional, Any, Callable, Sequence, Iterable +from typing import Dict, Optional, Any, Callable, Iterable import re import numpy as np import logging From 180fa2a01204af54f0bc5b327990077fb3791a45 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Wed, 28 Nov 2018 12:02:15 +0100 Subject: [PATCH 246/719] Fix test for metadata (due to use of atomic context manager) --- qcodes/tests/dataset/test_dataset_basic.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 9bd3440f82a..ccf6685ff21 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -684,13 +684,16 @@ def test_metadata(): badtag = 'lex luthor' sorry_metadata = {'superman': 1, badtag: None, 'spiderman': 'two'} - match = (f'Tag {badtag} has value None. ' - ' That is not a valid metadata value!') + bad_tag_msg = (f'Tag {badtag} has value None. ' + ' That is not a valid metadata value!') - with pytest.raises(ValueError, match=match): + with pytest.raises(RuntimeError, + match='Rolling back due to unhandled exception') as e: for tag, value in sorry_metadata.items(): ds1.add_metadata(tag, value) + assert error_caused_by(e, bad_tag_msg) + class TestGetData: x = ParamSpec("x", paramtype='numeric') From 0ddac10a8efbf83cf82e30976208af456642b981 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Wed, 28 Nov 2018 12:03:16 +0100 Subject: [PATCH 247/719] Remove redundant use of make_connection_plus_from --- qcodes/dataset/sqlite_base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index bdd58f41f4d..f817468deda 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -768,8 +768,7 @@ def atomic_transaction(conn: ConnectionPlus, sqlite cursor """ - conn_plus = make_connection_plus_from(conn) - with atomic(conn_plus) as atomic_conn: + with atomic(conn) as atomic_conn: c = transaction(atomic_conn, sql, *args) return c From efb6b89e2cd4810972c01f1dc40ae738fed3d0fe Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Wed, 28 Nov 2018 12:31:45 +0100 Subject: [PATCH 248/719] Fix test for atomic_transaction since only ConnectionPlus is allowed --- .../tests/dataset/test_sqlite_connection.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/qcodes/tests/dataset/test_sqlite_connection.py b/qcodes/tests/dataset/test_sqlite_connection.py index 6128fe59b9a..adbfc230584 100644 --- a/qcodes/tests/dataset/test_sqlite_connection.py +++ b/qcodes/tests/dataset/test_sqlite_connection.py @@ -290,18 +290,11 @@ def test_that_use_of_atomic_commits_only_at_outermost_context( assert 3 == len(control_conn.execute(get_all_runs).fetchall()) -@pytest.mark.parametrize(argnames='create_connection', - argvalues=( - sqlite3.connect, - lambda x: ConnectionPlus(sqlite3.connect(x))), - ids=( - 'sqlite3.Connection', - 'ConnectionPlus')) -def test_atomic_transaction(create_connection, tmp_path): - """Test that atomic_transaction works for both types of connection""" +def test_atomic_transaction(tmp_path): + """Test that atomic_transaction works for ConnectionPlus""" dbfile = str(tmp_path / 'temp.db') - conn = create_connection(dbfile) + conn = ConnectionPlus(sqlite3.connect(dbfile)) ctrl_conn = sqlite3.connect(dbfile) @@ -313,6 +306,19 @@ def test_atomic_transaction(create_connection, tmp_path): assert sql_create_table in ctrl_conn.execute(sql_table_exists).fetchall()[0] +def test_atomic_transaction_on_sqlite3_connection_raises(tmp_path): + """Test that atomic_transaction does not work for sqlite3.Connection""" + dbfile = str(tmp_path / 'temp.db') + + conn = sqlite3.connect(dbfile) + + match_str = re.escape('atomic context manager only accepts ConnectionPlus ' + 'database connection objects.') + + with pytest.raises(ValueError, match=match_str): + atomic_transaction(conn, 'whatever sql query') + + def test_connect(): conn = connect(':memory:') From 5b11e75b69d242d861004fe198c609b324fc4fec Mon Sep 17 00:00:00 2001 From: qSaevar Date: Wed, 28 Nov 2018 13:40:14 +0100 Subject: [PATCH 249/719] optimized imports --- qcodes/instrument_drivers/ZI/ZIHDAWG8.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py index d65fbd26c18..495f41b8e98 100644 --- a/qcodes/instrument_drivers/ZI/ZIHDAWG8.py +++ b/qcodes/instrument_drivers/ZI/ZIHDAWG8.py @@ -4,7 +4,8 @@ import textwrap import time from functools import partial -from typing import Optional, Any, List, Tuple, Union, Sequence, Dict +from typing import Any, List, Tuple, Union, Sequence, Dict + import zhinst.utils from qcodes import Instrument From 7dcc77c26e19d5fffd52ce0f79266de4bc85ed9e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 28 Nov 2018 13:57:35 +0100 Subject: [PATCH 250/719] Homogeneous coordinates for field vectors in Mercury iPS Adds functionality to FieldVector that allows for it to be used as a snapshotable parameter, and that adds conversion to and from homogeneous coordinate representations to make it easier to transform FieldVector instances. This functionality is used by the new field-valued parameters of the MercuryiPS instrument. This commit has been made via `git checkout -p` in order to take only changes of interest from a branch that contained more changes. In order to preserve the reference to the original author of this work, the "cherry picked from..." lines are added below. (cherry picked from commit f1bf38b54f266e52f86fdc03e59cb6cdbc6b400a) (cherry picked from commit 3c8a0a11cb082cf6ea21251ee17581c1a8d9e976) (cherry picked from commit 251a2f4d23b5b30e556b8954ce1fe4c938c75db7) (cherry picked from commit b31fa4643998fc9f51f85d56c183d4f257d955d3) (cherry picked from commit 5e23cd6d1d66c3a57b29850a5e784b426bc92822) --- qcodes/instrument/sims/MercuryiPS.yaml | 27 ++++ .../oxford/MercuryiPS_VISA.py | 50 +++++++- qcodes/math/field_vector.py | 121 ++++++++++++++++-- qcodes/tests/drivers/test_MercuryiPS.py | 23 +++- qcodes/tests/test_field_vector.py | 36 ++++++ qcodes/utils/helpers.py | 14 +- 6 files changed, 255 insertions(+), 16 deletions(-) diff --git a/qcodes/instrument/sims/MercuryiPS.yaml b/qcodes/instrument/sims/MercuryiPS.yaml index baf09369ce0..e489ac952d7 100644 --- a/qcodes/instrument/sims/MercuryiPS.yaml +++ b/qcodes/instrument/sims/MercuryiPS.yaml @@ -84,6 +84,33 @@ devices: q: "SET:DEV:GRPZ:PSU:ACTN:{}" r: "" + x ramp rate: + default: 0 + getter: + q: "READ:DEV:GRPX:PSU:SIG:RFST" + r: "{}" + setter: + q: "SET:DEV:GRPX:PSU:SIG:RFST:{}" + r: "" + + y ramp rate: + default: 0 + getter: + q: "READ:DEV:GRPY:PSU:SIG:RFST" + r: "{}" + setter: + q: "SET:DEV:GRPY:PSU:SIG:RFST:{}" + r: "" + + z ramp rate: + default: 0 + getter: + q: "READ:DEV:GRPZ:PSU:SIG:RFST" + r: "{}" + setter: + q: "SET:DEV:GRPZ:PSU:SIG:RFST:{}" + r: "" + resources: GPIB::1::INSTR: diff --git a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py index 0ad60dac98e..c2a3b421068 100644 --- a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py +++ b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py @@ -277,11 +277,48 @@ def __init__(self, name: str, address: str, visalib=None, unit='T', get_cmd=partial(self._get_measured, [coord])) + # FieldVector-valued parameters # + self.add_parameter(name="field_target", + label="target field", + unit="T", + get_cmd=self._get_target_field, + set_cmd=self._set_target_field) + self.add_parameter(name="field_measured", + label="measured field", + unit="T", + get_cmd=self._get_field) + + self.add_parameter(name="field_ramp_rate", + label="ramp rate", + unit="T/s", + get_cmd=self._get_ramp_rate, + set_cmd=self._set_ramp_rate) + self.connect_message() def _get_component(self, coordinate: str) -> float: return self._target_vector.get_components(coordinate)[0] + def _get_target_field(self) -> FieldVector: + return FieldVector( + **{ + coord: self._get_component(coord) + for coord in 'xyz' + } + ) + + def _get_ramp_rate(self) -> FieldVector: + return FieldVector( + x=self.GRPX.field_ramp_rate(), + y=self.GRPY.field_ramp_rate(), + z=self.GRPZ.field_ramp_rate(), + ) + + def _set_ramp_rate(self, rate : FieldVector) -> None: + self.GRPX.field_ramp_rate(rate.x) + self.GRPY.field_ramp_rate(rate.y) + self.GRPZ.field_ramp_rate(rate.z) + def _get_measured(self, coordinates: List[str]) -> Union[float, List[float]]: """ @@ -297,6 +334,13 @@ def _get_measured(self, coordinates: List[str]) -> Union[float, else: return meas_field.get_components(*coordinates) + def _get_field(self) -> FieldVector: + return FieldVector( + x=self.x_measured(), + y=self.y_measured(), + z=self.z_measured() + ) + def _set_target(self, coordinate: str, target: float) -> None: """ The function to set a target value for a coordinate, i.e. the set_cmd @@ -319,6 +363,10 @@ def _set_target(self, coordinate: str, target: float) -> None: for targ, slave in zip(cartesian_targ, self.submodules.values()): slave.field_target(targ) + def _set_target_field(self, field : FieldVector) -> None: + for coord in 'xyz': + self._set_target(coord, field[coord]) + def _idn_getter(self) -> Dict[str, str]: """ Parse the raw non-SCPI compliant IDN string into an IDN dict @@ -391,7 +439,7 @@ def set_new_field_limits(self, limit_func: Callable) -> None: self._field_limits = limit_func - def ramp(self, mode: str) -> None: + def ramp(self, mode : str = "safe") -> None: """ Ramp the fields to their present target value diff --git a/qcodes/math/field_vector.py b/qcodes/math/field_vector.py index e71139746e4..c7c4f21c40f 100644 --- a/qcodes/math/field_vector.py +++ b/qcodes/math/field_vector.py @@ -8,9 +8,14 @@ import numpy as np +from typing import Union, Type, TypeVar +NormOrder = Union[str, float] +T = TypeVar('T', bound='FieldVector') + class FieldVector(object): attributes = ["x", "y", "z", "r", "theta", "phi", "rho"] + repr_format = "cartesian" def __init__(self, x=None, y=None, z=None, r=None, theta=None, phi=None, rho=None): @@ -74,6 +79,9 @@ def _set_attribute_values(self, attr_names, values): for attr_name, value in zip(attr_names, values): self._set_attribute_value(attr_name, value) + def __getnewargs__(self): + return (self.x, self.y, self.z) + @staticmethod def _cartesian_to_other(x, y, z): """ Convert a cartesian set of coordinates to values of interest.""" @@ -145,7 +153,7 @@ def _compute_unknowns(self): self._set_attribute_values(FieldVector.attributes, new_values) break - def copy(self, other): + def copy(self : T, other : T): """Copy the properties of other vector to yourself""" for att in FieldVector.attributes: value = getattr(other, "_" + att) @@ -250,30 +258,127 @@ def is_equal(self, other): return True + def __getitem__(self, component): + return self.get_components(component)[0] + + def __setitem__(self, component, value): + self.set_component(**{component: value}) + + def __mul__(self, other): + if not isinstance(other, (float, int)): + return NotImplemented + + return FieldVector(**{ + component: self[component] * other + for component in 'xyz' + }) + + def __rmul__(self, other): + if not isinstance(other, (int, float)): + return NotImplemented + + return self * other + + def __neg__(self): + return -1 * self + + def __add__(self, other): + if not isinstance(other, FieldVector): + return NotImplemented + + return FieldVector(**{ + component: self[component] + other[component] + for component in 'xyz' + }) + + def __sub__(self, other): + if not isinstance(other, FieldVector): + return NotImplemented + + return FieldVector(**{ + component: self[component] - other[component] + for component in 'xyz' + }) + + # NB: we disable the pylint warning here so that we can match + # NumPy's naming convention for the norm method. + def norm(self, ord : NormOrder = 2) -> float: # pylint: disable=redefined-builtin + """ + Returns the norm of this field vector. See np.norm + for the definition of the ord keyword argument. + """ + return np.linalg.norm([self.x, self.y, self.z], ord=ord) + + def distance(self, other, ord : NormOrder = 2) -> float: # pylint: disable=redefined-builtin + return (self - other).norm(ord=ord) + @property - def x(self): + def x(self) -> float: return self._x @property - def y(self): + def y(self) -> float: return self._y @property - def z(self): + def z(self) -> float: return self._z @property - def rho(self): + def rho(self) -> float: return self._rho @property - def theta(self): + def theta(self) -> float: return np.degrees(self._theta) @property - def r(self): + def r(self) -> float: return self._r @property - def phi(self): + def phi(self) -> float: return np.degrees(self._phi) + + ## Representation Methods ## + + def repr_cartesian(self) -> str: + return f"FieldVector(x={self.x}, y={self.y}, z={self.z})" + + def repr_spherical(self) -> str: + return f"FieldVector(r={self.r}, phi={self.phi}, theta={self.theta})" + + def repr_cylindrical(self) -> str: + return f"FieldVector(rho={self.rho}, phi={self.phi}, z={self.z})" + + def __repr__(self) -> str: + if self.repr_format == "cartesian": + return self.repr_cartesian() + elif self.repr_format == "spherical": + return self.repr_spherical() + elif self.repr_format == "cylindrical": + return self.repr_cylindrical() + else: + return super().__repr__() + + ## Homogenous Coordinates ## + + def as_homogeneous(self) -> np.ndarray: + return np.array([self.x, self.y, self.z, 1]) + + @classmethod + def from_homogeneous(cls : Type[T], hvec : np.ndarray) -> T: + # Homogenous coordinates define an equivalence relation + # [x / s, y / s, z / s, 1] == [x, y, z, s]. + # More generally, + # [x, y, z, s] == [x', y', z', s'] + # iff x / s == x' / s', + # y / s == y' / s', and + # z / s == z' / s'. + # This definition has the consequence that for any + # w, w * [x, y, z, s] == [x, y, z, s]. + # Thus, we start by rescaling such that s == 1. + hvec /= hvec[-1] + return cls( + x=hvec[0], y=hvec[1], z=hvec[2] + ) diff --git a/qcodes/tests/drivers/test_MercuryiPS.py b/qcodes/tests/drivers/test_MercuryiPS.py index 3878e0032c7..09649f3f9f8 100644 --- a/qcodes/tests/drivers/test_MercuryiPS.py +++ b/qcodes/tests/drivers/test_MercuryiPS.py @@ -6,7 +6,7 @@ from qcodes.instrument_drivers.oxford.MercuryiPS_VISA import MercuryiPS import qcodes.instrument.sims as sims - +from qcodes.math.field_vector import FieldVector visalib = sims.__file__.replace('__init__.py', 'MercuryiPS.yaml@sim') @@ -68,6 +68,21 @@ def test_simple_setting(driver): assert driver.GRPX.field_target() == 0.1 +def test_vector_setting(driver): + assert driver.field_target().distance(FieldVector(0, 0, 0)) <= 1e-8 + driver.field_target(FieldVector(r=0.1, theta=0, phi=0)) + assert driver.field_target().distance( + FieldVector(r=0.1, theta=0, phi=0) + ) <= 1e-8 + + +def test_vector_ramp_rate(driver): + driver.field_ramp_rate(FieldVector(0.1, 0.1, 0.1)) + assert driver.field_ramp_rate().distance( + FieldVector(0.1, 0.1, 0.1) + ) <= 1e-8 + + def test_wrong_field_limit_raises(): # check that a non-callable input fails @@ -133,10 +148,8 @@ def test_ramp_safely(driver, x, y, z, caplog): driver.GRPZ.ramp_status('HOLD') # the current field values are always zero for the sim. instr. - - driver.x_target(x) - driver.y_target(y) - driver.z_target(z) + # Use the FieldVector interface here to increase coverage. + driver.field_target(FieldVector(x=x, y=y, z=z)) exp_order = np.array(['x', 'y', 'z'])[np.argsort(np.abs(np.array([x, y, z])))] diff --git a/qcodes/tests/test_field_vector.py b/qcodes/tests/test_field_vector.py index b5f56b424b4..f41650c99bd 100644 --- a/qcodes/tests/test_field_vector.py +++ b/qcodes/tests/test_field_vector.py @@ -3,11 +3,13 @@ implemented. """ import numpy as np +import json from hypothesis import given, settings from hypothesis.strategies import floats from hypothesis.strategies import tuples from qcodes.math.field_vector import FieldVector +from qcodes.utils.helpers import NumpyJSONEncoder random_coordinates = { "cartesian": tuples( @@ -82,3 +84,37 @@ def test_cylindrical_properties(cylindrical0): cartisian1 = FieldVector(**cylindrical1).get_components("x", "y", "z") assert np.allclose(cartisian0, cartisian1 * np.array([-1, -1, 1])) + +@given( + random_coordinates["cylindrical"], + random_coordinates["spherical"] +) +@settings(max_examples=10) +def test_triangle_inequality(cylindrical0, spherical0): + cylindrical0 = FieldVector(**dict(zip(["rho", "phi", "z"], cylindrical0))) + spherical0 = FieldVector(**dict(zip(["r", "phi", "theta"], spherical0))) + + assert (cylindrical0 + spherical0).norm() <= (cylindrical0.norm() + spherical0.norm()) + assert cylindrical0.distance(spherical0) <= (cylindrical0.norm() + spherical0.norm()) + +@given(random_coordinates["cartesian"]) +@settings(max_examples=10) +def test_homogeneous_roundtrip(cartesian0): + vec = FieldVector(**dict(zip("xyz", cartesian0))) + h_vec = 13 * vec.as_homogeneous() + + assert np.allclose( + vec.get_components(*"xyz"), + FieldVector.from_homogeneous(h_vec).get_components(*"xyz") + ) + +@given(random_coordinates["spherical"]) +@settings(max_examples=10) +def test_json_dump(spherical0): + vec = FieldVector(**dict(zip(["r", "phi", "theta"], spherical0))) + dump = json.dumps(vec, cls=NumpyJSONEncoder) + + assert json.loads(dump) == { + '__class__': FieldVector.__name__, + '__args__': [vec.x, vec.y, vec.z] + } diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index 53757b65288..4c55395fe8a 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -46,6 +46,8 @@ def default(self, obj): "__dtype__" containing value "complex" * object with a `_JSONEncoder` method get converted the return value of that method + * objects which support the pickle protocol get converted using the data + provided by that protocol * other objects which cannot be serialized get converted to their string representation (suing the `str` function) """ @@ -70,8 +72,16 @@ def default(self, obj): try: s = super(NumpyJSONEncoder, self).default(obj) except TypeError: - # we cannot convert the object to JSON, just take a string - s = str(obj) + # See if the object supports the pickle protocol. + # If so, we should be able to use that to serialize. + if hasattr(obj, '__getnewargs__'): + return { + '__class__': type(obj).__name__, + '__args__': obj.__getnewargs__() + } + else: + # we cannot convert the object to JSON, just take a string + s = str(obj) return s From cd5401f856d166df46e0d95ab831f5faa68c996b Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Wed, 28 Nov 2018 14:08:41 +0100 Subject: [PATCH 251/719] Pass fixture directly into metadata test instead of mark decorator --- qcodes/tests/dataset/test_dataset_basic.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index ccf6685ff21..52b28941bcd 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -662,8 +662,7 @@ def test_get_description(some_paramspecs): assert loaded_ds.description == desc -@pytest.mark.usefixtures('experiment') -def test_metadata(): +def test_metadata(experiment): metadata1 = {'number': 1, "string": "Once upon a time..."} metadata2 = {'more': 'meta'} From 10f735d30a75d655abfdffdbbb9f72edc078b34f Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 14:14:30 +0100 Subject: [PATCH 252/719] add `get_columns` --- qcodes/dataset/sqlite_base.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 2dde25d5f9e..374dc4cdc4d 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1128,6 +1128,38 @@ def get_data(conn: SomeConnection, return res +def get_columns(conn: SomeConnection, + table_name: str, + columns: List[str], + start: int = None, + end: int = None) -> Dict[str, np.ndarray]: + """ + Get data from the columns of a table. + Allows to specfiy a range. + + Args: + conn: database connection + table_name: name of the table + columns: list of columns + start: start of range (1 indedex) + end: start of range (1 indedex) + + Returns: + the data requested + """ + # Benchmarking shows that transposing the data with python types is faster + # than transposing the data using np.array.transpose + # This method is going to form the entry point for a compiled version + + query = _get_data_query(table_name, columns, start, end) + c = atomic_transaction(conn, query) + res = many_many(c, *columns) + res_t = list(map(list, zip(*res))) + return {name: np.array(column) + for name, column + in zip(res_t, columns)} + + def get_values(conn: SomeConnection, table_name: str, param_name: str) -> List[List[Any]]: From cc6b838c42e9bf79987c69fac5d103d5cc77cd39 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 15:26:24 +0100 Subject: [PATCH 253/719] insert missing hunk for _build_data_query --- qcodes/dataset/sqlite_base.py | 51 ++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 374dc4cdc4d..a2d19a4ba72 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1084,6 +1084,30 @@ def length(conn: SomeConnection, return _len +def _build_data_query( table_name: str, + columns: List[str], + start: Optional[int] = None, + end: Optional[int] = None, + ) -> str: + + _columns = ",".join(columns) + query = f""" + SELECT {_columns} + FROM "{table_name}" + """ + + start_specified = start is not None + end_specified = end is not None + + where = ' WHERE' if start_specified or end_specified else '' + start_condition = f' rowid >= {start}' if start_specified else '' + end_condition = f' rowid <= {end}' if end_specified else '' + and_ = ' AND' if start_specified and end_specified else '' + + query += where + start_condition + and_ + end_condition + return query + + def get_data(conn: SomeConnection, table_name: str, columns: List[str], @@ -1105,23 +1129,8 @@ def get_data(conn: SomeConnection, Returns: the data requested in the format of list of rows of values """ - _columns = ",".join(columns) - - query = f""" - SELECT {_columns} - FROM "{table_name}" - """ - - start_specified = start is not None - end_specified = end is not None - - where = ' WHERE' if start_specified or end_specified else '' - start_condition = f' rowid >= {start}' if start_specified else '' - end_condition = f' rowid <= {end}' if end_specified else '' - and_ = ' AND' if start_specified and end_specified else '' - - query += where + start_condition + and_ + end_condition + query = _build_data_query(table_name, columns, start, end) c = atomic_transaction(conn, query) res = many_many(c, *columns) @@ -1151,13 +1160,11 @@ def get_columns(conn: SomeConnection, # than transposing the data using np.array.transpose # This method is going to form the entry point for a compiled version - query = _get_data_query(table_name, columns, start, end) - c = atomic_transaction(conn, query) - res = many_many(c, *columns) + res = get_data(conn, table_name, columns, start, end) res_t = list(map(list, zip(*res))) - return {name: np.array(column) - for name, column - in zip(res_t, columns)} + return {name: np.array(column_data) + for name, column_data + in zip(columns, res_t)} def get_values(conn: SomeConnection, From cc8141f3b15fbf5efba0d6d0049a638005534b32 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 15:26:46 +0100 Subject: [PATCH 254/719] add tests --- qcodes/tests/dataset/dataset_fixtures.py | 31 ++++++++++++++++++++++++ qcodes/tests/dataset/test_sqlite_base.py | 26 ++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 qcodes/tests/dataset/dataset_fixtures.py diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py new file mode 100644 index 00000000000..ca79a46a178 --- /dev/null +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -0,0 +1,31 @@ +import pytest +import numpy as np +from qcodes.dataset.param_spec import ParamSpec + +# pylint: disable=unused-import +from qcodes.tests.dataset.temporary_databases import dataset +# pylint: enable=unused-import + + +@pytest.fixture +def scalar_dataset(dataset): + n_params = 3 + n_rows = 10**3 + params_indep = [ParamSpec(f'param_{i}', + 'numeric', + label=f'param_{i}', + unit='V') + for i in range(n_params)] + params = params_indep + [ParamSpec(f'param_{n_params}', + 'numeric', + label=f'param_{n_params}', + unit='Ohm', + depends_on=params_indep)] + for p in params: + dataset.add_parameter(p) + dataset.add_results([{p.name: np.random.rand(1)[0] for p in params} + for _ in range(n_rows)]) + dataset.mark_complete() + yield dataset + + diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index fc309304aac..799a869f777 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -9,6 +9,7 @@ import hypothesis.strategies as hst from hypothesis import given import unicodedata +import numpy as np from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -19,8 +20,10 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import \ empty_temp_db, experiment, dataset +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset from qcodes.tests.dataset.test_database_creation_and_upgrading import \ error_caused_by +# pylint: enable=unused-import _unicode_categories = ('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nd', 'Pc', 'Pd', 'Zs') @@ -185,3 +188,26 @@ def test_runs_table_columns(empty_temp_db): colnames.remove(row['name']) assert colnames == [] + + +def test_get_columns(scalar_dataset): + ds = scalar_dataset + params = ds.parameters.split(',') + # delete some random parameter to test it with an incomplete list + del params[-2] + + ref = mut.get_data(ds.conn, ds.table_name, params) + dut = mut.get_columns(ds.conn, ds.table_name, params) + for i_row, row in enumerate(ref): + for i_param, param_name in enumerate(params): + v_ref = row[i_param] + v_test = dut[param_name][i_row] + if type(v_ref) == float: + assert type(v_test) == np.float64 + elif type(v_ref) == int: + assert type(v_test) == np.int + else: + raise RuntimeError('Unsupported data type') + assert np.isclose(v_test, v_ref) + + From e4df3d5c87f85e97de02482cf7279bc869d8e190 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Wed, 28 Nov 2018 15:40:19 +0100 Subject: [PATCH 255/719] Make another subscriber test more robust --- qcodes/tests/dataset/test_subscribing.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_subscribing.py b/qcodes/tests/dataset/test_subscribing.py index 397283664ef..0596010049a 100644 --- a/qcodes/tests/dataset/test_subscribing.py +++ b/qcodes/tests/dataset/test_subscribing.py @@ -85,7 +85,13 @@ def test_basic_subscription(dataset, basic_subscriber): y = -x**2 dataset.add_result({'x': x, 'y': y}) expected_state[x+1] = [(x, y)] - assert dataset.subscribers[sub_id].state == expected_state + + @retry_until_does_not_throw( + exception_class_to_expect=AssertionError, delay=0, tries=10) + def assert_expected_state(): + assert dataset.subscribers[sub_id].state == expected_state + + assert_expected_state() dataset.unsubscribe(sub_id) @@ -161,7 +167,7 @@ def assert_expected_state(): assert dataset.subscribers[sub_id].state == expected_state assert dataset.subscribers[sub_id_c].state == expected_state - assert_expected_state() + assert_expected_state() def test_subscription_from_config_wrong_name(dataset): From b561b98ef103eca89cc3919b39c7e64449bb1c74 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 15:54:37 +0100 Subject: [PATCH 256/719] rename get_colums->get_parameter_data --- qcodes/dataset/sqlite_base.py | 10 +++++----- qcodes/tests/dataset/test_sqlite_base.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index a2d19a4ba72..981f160dc56 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1137,11 +1137,11 @@ def get_data(conn: SomeConnection, return res -def get_columns(conn: SomeConnection, - table_name: str, - columns: List[str], - start: int = None, - end: int = None) -> Dict[str, np.ndarray]: +def get_parameter_data(conn: SomeConnection, + table_name: str, + columns: List[str], + start: int = None, + end: int = None) -> Dict[str, np.ndarray]: """ Get data from the columns of a table. Allows to specfiy a range. diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 799a869f777..7353a08c4f9 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -190,14 +190,14 @@ def test_runs_table_columns(empty_temp_db): assert colnames == [] -def test_get_columns(scalar_dataset): +def test_get_parameter_data(scalar_dataset): ds = scalar_dataset params = ds.parameters.split(',') # delete some random parameter to test it with an incomplete list del params[-2] ref = mut.get_data(ds.conn, ds.table_name, params) - dut = mut.get_columns(ds.conn, ds.table_name, params) + dut = mut.get_parameter_data(ds.conn, ds.table_name, params) for i_row, row in enumerate(ref): for i_param, param_name in enumerate(params): v_ref = row[i_param] From 5ea0f029cccbf6ab446bc958763d400e1814f643 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 15:54:52 +0100 Subject: [PATCH 257/719] implement in DataSet --- qcodes/dataset/data_set.py | 71 ++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 7f93402a935..ceaa855bc23 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -673,6 +673,29 @@ def add_parameter_values(self, spec: ParamSpec, values: VALUES): results = [{spec.name: value} for value in values] self.add_results(results) + @staticmethod + def _validate_parameters(*params: Union[str, ParamSpec, _BaseParameter] + ) -> List[str]: + """ + validate the provided parameters have a name and return them as a list. + names. The Parameters may be a mix of strings, ParamSpecs or ordinary + QCoDeS parameters. + """ + + valid_param_names = [] + for maybeParam in params: + if isinstance(maybeParam, str): + valid_param_names.append(maybeParam) + continue + else: + try: + maybeParam = maybeParam.name + except Exception as e: + raise ValueError( + "This parameter does not have a name") from e + valid_param_names.append(maybeParam) + return valid_param_names + def get_data(self, *params: Union[str, ParamSpec, _BaseParameter], start: Optional[int] = None, @@ -708,21 +731,41 @@ def get_data(self, be of the datatypes stored in the database (numeric, array or string) """ - valid_param_names = [] - for maybeParam in params: - if isinstance(maybeParam, str): - valid_param_names.append(maybeParam) - continue - else: - try: - maybeParam = maybeParam.name - except Exception as e: - raise ValueError( - "This parameter does not have a name") from e - valid_param_names.append(maybeParam) - data = get_data(self.conn, self.table_name, valid_param_names, + valid_param_names = self._validate_parameters(*params) + return get_data(self.conn, self.table_name, valid_param_names, + start, end) + + def get_parameter_data( + self, + *params: Union[str, ParamSpec, _BaseParameter], + start: Optional[int] = None, + end: Optional[int] = None) -> Dict[str, numpy.ndarray]: + """ + Returns the values stored in the DataSet for the specified parameters. + The values are returned as a dictionary of numpy arrays where the key, + is given by the respective parameter name and the value arrays represent + the data points. This method returns the transpose of `get_data`. + + If provided, the start and end arguments select a range of results + by result count (index). If the range is empty - that is, if the end is + less than or equal to the start, or if start is after the current end + of the DataSet – then a list of empty arrays is returned. + + Args: + *params: string parameter names, QCoDeS Parameter objects, and + ParamSpec objects + start: start value of selection range (by result count); ignored + if None + end: end value of selection range (by results count); ignored if + None + + Returns: + Dictionary of numpy arrays containing the data points of type + numeric, array or string. + """ + valid_param_names = self._validate_parameters(*params) + return get_parameter_data(self.conn, self.table_name, valid_param_names, start, end) - return data def get_values(self, param_name: str) -> List[List[Any]]: """ From 041eeb9affe129b46ccc0c4cd8809e3564cd4d9e Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 16:36:40 +0100 Subject: [PATCH 258/719] add imports --- qcodes/dataset/data_set.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index ceaa855bc23..5cd561aa921 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -7,6 +7,7 @@ import logging import uuid from queue import Queue, Empty +import numpy from qcodes.dataset.param_spec import ParamSpec from qcodes.instrument.parameter import _BaseParameter @@ -22,6 +23,7 @@ modify_many_values, insert_values, insert_many_values, VALUE, VALUES, get_data, + get_parameter_data, get_values, get_setpoints, get_metadata, From e15cfcbd48afec69f0363f419eda5c28c0774305 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Wed, 28 Nov 2018 16:37:03 +0100 Subject: [PATCH 259/719] add dataset test --- qcodes/tests/dataset/test_dataset_basic.py | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 1a23d894091..2ffad6bd1ba 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1,4 +1,5 @@ import itertools +from copy import copy import pytest import numpy as np @@ -17,6 +18,7 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -614,3 +616,27 @@ def ds_with_vals(self, dataset): def test_get_data_with_start_and_end_args(self, ds_with_vals, start, end, expected): assert expected == ds_with_vals.get_data(self.x, start=start, end=end) + +def test_get_parameter_data(scalar_dataset): + ds = scalar_dataset + params = ds.parameters.split(',') + # delete some random parameter to test it with an incomplete list + del params[-2] + # replace first list entry by paramspec + param_names = copy(params) + params[0] = ds.paramspecs[params[0]] + + ref = ds.get_data(*params) + dut = ds.get_parameter_data(*params) + + for i_row, row in enumerate(ref): + for i_param, param_name in enumerate(param_names): + v_ref = row[i_param] + v_test = dut[param_name][i_row] + if type(v_ref) == float: + assert type(v_test) == np.float64 + elif type(v_ref) == int: + assert type(v_test) == np.int + else: + raise RuntimeError('Unsupported data type') + assert np.isclose(v_test, v_ref) From ae21c0e9fcb70e4796f3583560a0949cb3b9574a Mon Sep 17 00:00:00 2001 From: "Robert R. Henry" Date: Wed, 28 Nov 2018 14:54:59 -0800 Subject: [PATCH 260/719] Fix some typos, grammar glitches and minor python formatting. --- docs/community/objects.rst | 2 +- docs/dataset/introduction.rst | 2 +- .../Comprehensive Plotting How-To.ipynb | 18 +++++++++--------- .../DataSet/Offline Plotting Tutorial.ipynb | 4 ++-- docs/examples/plotting/live_plotting.ipynb | 2 +- docs/user/tutorial.rst | 14 +++++++------- .../QuantumDesign/DynaCoolPPMS/DynaCool.py | 2 +- .../tektronix/Keithley_2600.py | 2 +- .../tektronix/Keithley_2600_channels.py | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/community/objects.rst b/docs/community/objects.rst index 559b09177e0..3b37576f612 100644 --- a/docs/community/objects.rst +++ b/docs/community/objects.rst @@ -8,7 +8,7 @@ Rough linkages: In **bold** the containing class creates this object. In *italics* the container just holds this object (or class) as a default for derivatives -to use. Normal text the container includes and uses this object. +to use. Normal text shows the container includes and uses of this object. - Station - Instrument: IPInstrument, VisaInstrument, MockInstrument diff --git a/docs/dataset/introduction.rst b/docs/dataset/introduction.rst index f7409084875..5f7e1e3410c 100644 --- a/docs/dataset/introduction.rst +++ b/docs/dataset/introduction.rst @@ -11,7 +11,7 @@ This page explains the basics of the QCoDeS dataset. Read here to figure out wha Basics ====== -The DataSet is directly linked to an SQLite database on the machine hard drive. Here we provide an overview of the layout of that database. +The DataSet is directly linked to an SQLite database on the host machine's hard drive. Here we provide an overview of the layout of that database. The specifics of the python objects implementing the API on top of that can be found in the section :ref:`datasetdesign`. The database holds a number of ``Experiments`` that each holds a number of ``DataSets``. One ``DataSet`` contains exactly one ``run``, and we may use the words ``DataSet`` and ``run`` interchangeably. diff --git a/docs/examples/Comprehensive Plotting How-To.ipynb b/docs/examples/Comprehensive Plotting How-To.ipynb index 5e75fbbc31b..88ae99df9b4 100644 --- a/docs/examples/Comprehensive Plotting How-To.ipynb +++ b/docs/examples/Comprehensive Plotting How-To.ipynb @@ -23,7 +23,7 @@ "Plotting data in QCoDeS can be done using either MatPlot or QTPlot, with matplotlib and pyqtgraph as backends, respectively. \n", "MatPlot and QTPlot tailor these plotting backends to QCoDeS, providing many features.\n", "For example, when plotting a DataArray in a DataSet, the corresponding ticks, labels, etc. are automatically added to the plot.\n", - "Both MatPlot and QTPlot support live plotting while a measurement is running\n", + "Both MatPlot and QTPlot support live plotting while a measurement is running.\n", "\n", "One of the main differences between the two backends is that matplotlib is more strongly integrated with Jupyter Notebook, while pyqtgraph uses the PyQT GUI.\n", "For matplotlib, this has the advantage that plots can be displayed within a notebook (though it also has a gui).\n", @@ -39,7 +39,7 @@ "outputs": [], "source": [ "loc_provider = qc.data.location.FormatLocation(fmt='data/{date}/#{counter}_{name}_{time}')\n", - "qc.data.data_set.DataSet.location_provider=loc_provider" + "qc.data.data_set.DataSet.location_provider = loc_provider" ] }, { @@ -921,7 +921,7 @@ "# Attach updating of plot to loop\n", "loop.with_bg_task(plot.update)\n", "\n", - "loop.run();" + "loop.run()" ] }, { @@ -1786,7 +1786,7 @@ "# Attach updating of plot to loop\n", "loop.with_bg_task(plot.update)\n", "\n", - "loop.run();" + "loop.run()" ] }, { @@ -2627,7 +2627,7 @@ "# Attach updating of plot to loop\n", "loop.with_bg_task(plot.update)\n", "\n", - "loop.run();" + "loop.run()" ] }, { @@ -2635,7 +2635,7 @@ "metadata": {}, "source": [ "Note that we passed the kwarg `subplots=3` to specify that we need 3 subplots.\n", - "the `subplots` kwarg can be either an int or a tuple.\n", + "The `subplots` kwarg can be either an int or a tuple.\n", "If it is an int, it will segment the value such that there are at most three columns.\n", "If a tuple is provided, its first element indicates the number of rows, and the second the number of columns.\n", "\n", @@ -3494,7 +3494,7 @@ "# Attach updating of plot to loop\n", "loop.with_bg_task(plot.update)\n", "\n", - "loop.run();" + "loop.run()" ] }, { @@ -4341,7 +4341,7 @@ "# Attach updating of plot to loop\n", "loop.with_bg_task(plot.update)\n", "\n", - "loop.run();" + "loop.run()" ] }, { @@ -4410,7 +4410,7 @@ "Every time a new plot is created, it will update the active axis and figure.\n", "The active Figure and Axis can be changed via `plt.scf(fig)` and `plt.sca(ax)`, respectively.\n", "\n", - "As an example, the following code will change the title of the last-created plot (the right subplot of the previous figure)" + "As an example, the following code will change the title of the last-created plot (the right subplot of the previous figure):" ] }, { diff --git a/docs/examples/DataSet/Offline Plotting Tutorial.ipynb b/docs/examples/DataSet/Offline Plotting Tutorial.ipynb index ad2f7b82433..be4b13fe34b 100644 --- a/docs/examples/DataSet/Offline Plotting Tutorial.ipynb +++ b/docs/examples/DataSet/Offline Plotting Tutorial.ipynb @@ -115,9 +115,9 @@ "\n", "xvals = np.linspace(-3.4, 4.2, 250)\n", "\n", - "# shuffle randomly the values in order to test that plot\n", + "# Randomly shuffle the values in order to test the plot\n", "# that is to be created for this data is a correct line\n", - "# that does not depend on the order of the data\n", + "# that does not depend on the order of the data.\n", "np.random.shuffle(xvals)\n", "\n", "with meas.run() as datasaver:\n", diff --git a/docs/examples/plotting/live_plotting.ipynb b/docs/examples/plotting/live_plotting.ipynb index edf8c465b2a..4375831ce9b 100644 --- a/docs/examples/plotting/live_plotting.ipynb +++ b/docs/examples/plotting/live_plotting.ipynb @@ -44,7 +44,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With this simple chang you can run all your notebooks without any changes and live data will be streamed to plottr. For that lets consider the simple example adapted from the dataset docs:" + "With this simple change you can run all your notebooks without any changes and live data will be streamed to plottr. For that let us consider the simple example adapted from the dataset docs:" ] }, { diff --git a/docs/user/tutorial.rst b/docs/user/tutorial.rst index 65fc0cedbac..4199ad6fab1 100644 --- a/docs/user/tutorial.rst +++ b/docs/user/tutorial.rst @@ -119,7 +119,7 @@ and we save the sum of them. z_vals = np.linspace(1, 2, 2) loop = qc.Loop(magnet.sweep(x_vals, y_vals, z_vals), delay=0.001).each(p4) - data =loop.run() + data = loop.run() @@ -134,8 +134,8 @@ Meta Instruments The concept of a meta instrument is that of having two separate Instrument, real or virtual, whose actions can the be controlled from the meta instrument. -In the following example we will create two dummy instruments and a meta instruments. -All the instruments will live on a InstrumentServer. +In the following example we will create two dummy instruments and a meta instrument. +All the instruments will live on an InstrumentServer. .. note:: this is rather non-trival due to the limitation of the @@ -254,9 +254,9 @@ Async Meta Say you want to set two instruments at the same time. You can use the following: -.. note:: the curernt architecture is so that you MUST one server per base instrument +.. note:: the current architecture is so that you MUST one server per base instrument -The base instrument class stays the same, meta gets a new method f.ex: +The base instrument class stays the same, Meta gets a new method for example: .. code:: python @@ -303,12 +303,12 @@ The base instrument class stays the same, meta gets a new method f.ex: This way: >>> meta.setBothAsync(0) -will set both instrument at the same time, say it takes 10 seconds per set, +will set both instruments at the same time, say it takes 10 seconds per set, then setting two things will take 10 seconds, not 20 seconds. For a complete working example see :download:`this example script <./meta.py>`. -Avanced +Advanced ------- .. todo:: missing diff --git a/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py b/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py index 2168453b258..7359307ef00 100644 --- a/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py +++ b/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py @@ -17,7 +17,7 @@ class DynaCool(VisaInstrument): Args: name: The name used internaly by QCoDeS for this driver - address: The VISA ressource name. + address: The VISA resource name. E.g. 'TCPIP0::127.0.0.1::5000::SOCKET' with the appropriate IP address instead of 127.0.0.1. Note that the port number is hard-coded into the server. diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600.py b/qcodes/instrument_drivers/tektronix/Keithley_2600.py index 78d79aba78c..f92f55602ff 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_2600.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_2600.py @@ -22,7 +22,7 @@ def __init__(self, name: str, address: str, channel: str, """ Args: name: Name to use internally in QCoDeS - address: VISA ressource address + address: VISA resource address channel: Either 'a' or 'b' model: The model type, e.g. '2614B' """ diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py index a1784036ad0..5592ffd0bec 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py @@ -349,7 +349,7 @@ def __init__(self, name: str, address: str, **kwargs) -> None: """ Args: name: Name to use internally in QCoDeS - address: VISA ressource address + address: VISA resource address """ super().__init__(name, address, terminator='\n', **kwargs) From 7cf8e2020cecd19d0cdd640c4c43cbfcac038786 Mon Sep 17 00:00:00 2001 From: "Robert R. Henry" Date: Wed, 28 Nov 2018 15:44:19 -0800 Subject: [PATCH 261/719] Fix 'title underline too short' issue which breaks CI. --- docs/user/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/tutorial.rst b/docs/user/tutorial.rst index 4199ad6fab1..ae0bcd42af0 100644 --- a/docs/user/tutorial.rst +++ b/docs/user/tutorial.rst @@ -309,6 +309,6 @@ then setting two things will take 10 seconds, not 20 seconds. For a complete working example see :download:`this example script <./meta.py>`. Advanced -------- +-------- .. todo:: missing From 2b440c1c78653bbdd1bdd1a48e10a01bef16bb19 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 28 Nov 2018 16:42:22 -0800 Subject: [PATCH 262/719] added instrument sim yaml file --- qcodes/instrument/sims/Keithley_s46.yaml | 54 ++++++++++++ .../tektronix/Keithley_s46.py | 82 +++++++++++++------ qcodes/tests/drivers/test_keithley_s46.py | 59 +++++++++++++ 3 files changed, 171 insertions(+), 24 deletions(-) create mode 100644 qcodes/instrument/sims/Keithley_s46.yaml create mode 100644 qcodes/tests/drivers/test_keithley_s46.py diff --git a/qcodes/instrument/sims/Keithley_s46.yaml b/qcodes/instrument/sims/Keithley_s46.yaml new file mode 100644 index 00000000000..0b9bcca7605 --- /dev/null +++ b/qcodes/instrument/sims/Keithley_s46.yaml @@ -0,0 +1,54 @@ +# SIMULATED INSTRUMENT FOR Keysight 33xxx series function generator +spec: "1.0" +devices: + device bad_state: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "KEITHLEY INSTRUMENTS INC.,MODEL SYSTEM 46, 1327388, A03 " + - q: ":CONF:CPOL?" + r: "6,6,6,6,0,0,0,0,1,0,0,1" + + properties: + + close: + getter: + q: ":CLOS?" + r: "(@1,2,8)" + + device default: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "KEITHLEY INSTRUMENTS INC.,MODEL SYSTEM 46, 1327388, A03 " + - q: ":CONF:CPOL?" + r: "6,6,6,6,0,0,0,0,1,0,0,1" + + properties: + + close: + getter: + q: ":CLOS?" + r: "(@1,8,13)" + setter: + q: ":CLOS {}" + r: "" + + open: + setter: + q: ":OPEN {}" + r: "" + +resources: + GPIB::1::INSTR: + device: device bad_state + GPIB::2::INSTR: + device: device default \ No newline at end of file diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 9116c3ee7e3..4c2acdb4b04 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -1,37 +1,50 @@ import numpy as np import itertools from collections import defaultdict +import re from qcodes import VisaInstrument, InstrumentChannel, ChannelList +from qcodes.utils.validators import Enum class ChannelNotPresentError(Exception): pass +class LockAcquisitionError(Exception): + pass + + class RelayLock: def __init__(self): - self.acquired = False - self.acquired_by = None + self._acquired = False + self._acquired_by = None def acquire(self, requester_id): - if self.acquired and self.acquired_by != requester_id: - raise RuntimeError( + if self._acquired and self._acquired_by != requester_id: + raise LockAcquisitionError( f"Relay already in use by channel {self.acquired_by}" ) - self.acquired = True - self.acquired_by = requester_id + self._acquired = True + self._acquired_by = requester_id def release(self, requester_id): - if self.acquired_by != requester_id: + if self._acquired_by != requester_id: + # It should be impossible to get here. There is a driver bug + # if we do. raise RuntimeError( f"Relay can only be freed by channel {self.acquired_by} " - f"that acquired the lock" + f"that acquired the lock. Please get in touch with a QCoDeS " + f"developer to get to the root cause of this error" ) - self.acquired = False - self.acquired_by = None + self._acquired = False + self._acquired_by = None + + @property + def acquired_by(self): + return self._acquired_by class RFSwitchChannel(InstrumentChannel): @@ -42,17 +55,29 @@ def __init__(self, parent, name, channel_number, relay_locks): self._relay_id = self._get_relay() self._relay_lock = relay_locks[self._relay_id] + if self._get_state() == "close": + try: + self._relay_lock.acquire(self._channel_number) + except LockAcquisitionError as e: + raise RuntimeError( + "The driver is initialized from an undesirable instrument " + "state where more then one channel on a single relay is " + "closed. It is advised to power cycle the instrument or to " + "manually send the 'OPEN:ALL' SCPI command to get the " + "instrument back into a normal state. Refusing to " + "initialize driver!" + ) from e + self.add_parameter( - "close", - get_cmd=lambda: str(self._channel_number) in self.ask(":CONF:CPOL?"), - set_cmd=lambda state: { - True: self._close_channel, - False: self._open_channel - }[state]() + "state", + get_cmd=self._get_state, + set_cmd=f":{{}} (@{self._channel_number})", + set_parser=self._set_state_parser, + vals=Enum("open", "close") ) def _get_relay(self): - relay_layout = self.parent.relay_layout() + relay_layout = self.parent.relay_layout found = False count = 0 @@ -64,15 +89,24 @@ def _get_relay(self): if not found: raise ChannelNotPresentError() - return (["A", "B", "C", "D"] + [chr(i) for i in range(1, 9)])[count] + return (["A", "B", "C", "D"] + [str(i) for i in range(1, 9)])[count] + + def _get_state(self): + closed_channels = re.findall(r"(\d+)[,)]", self.ask(":CLOS?")) + return "close" \ + if str(self._channel_number) in closed_channels \ + else "open" + + def _set_state_parser(self, new_state: str): + + if new_state == "close": + self._relay_lock.acquire(self._channel_number) + elif new_state == "open" \ + and self._relay_lock.acquired_by == self._channel_number: - def _close_channel(self): - self._relay_lock.acquire(self._channel_number) - self.write(f":CLOSE (@{self._channel_number})") + self._relay_lock.release(self._channel_number) - def _open_channel(self): - self._relay_lock.release(self._channel_number) - self.write(f":OPEN (@{self._channel_number})") + return new_state.upper() @property def relay_id(self): diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py new file mode 100644 index 00000000000..13f29a400d0 --- /dev/null +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -0,0 +1,59 @@ +import pytest + +from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( + S46, LockAcquisitionError +) + +import qcodes.instrument.sims as sims +visalib = sims.__file__.replace('__init__.py', 'Keithley_s46.yaml@sim') + + +@pytest.fixture(scope='module') +def s46(): + driver = S46('s46_sim',address='GPIB::2::INSTR', visalib=visalib) + yield driver + driver.close() + + +def test_runtime_error_on_bad_init(): + + with pytest.raises( + RuntimeError, + match="The driver is initialized from an undesirable instrument state" + ): + S46('s46_bad_state', address='GPIB::1::INSTR', visalib=visalib) + + +def test_init(s46): + + n_channels = len(s46.channels) + assert n_channels == 26 + + closed_channels = [0, 7, 12] + + for channel_nr in range(n_channels): + assert s46.channels[channel_nr].state() == "close" \ + if channel_nr in closed_channels else "open" + + +def test_open_close(s46): + + with pytest.raises( + LockAcquisitionError, + match="Relay already in use by channel" + ): + s46.channels[1].state("close") + + s46.channels[0].state("open") + s46.channels[1].state("close") + + s46.channels[18].state("close") + + with pytest.raises( + LockAcquisitionError, + match="Relay already in use by channel" + ): + s46.channels[19].state("close") + + s46.channels[18].state("open") + s46.channels[19].state("close") From 6aed56fb82a257a88d2af7cf1b6ad435e2dd2d0d Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 29 Nov 2018 09:22:24 +0100 Subject: [PATCH 263/719] handle empty parameter list --- qcodes/dataset/data_set.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 5cd561aa921..face1f8302a 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -734,6 +734,10 @@ def get_data(self, string) """ valid_param_names = self._validate_parameters(*params) + if len(valid_param_names) == 0: + raise RuntimeError('Error calling `get_data`: you need to supply ' + 'at least one parameter for which to get the ' + 'data.') return get_data(self.conn, self.table_name, valid_param_names, start, end) From 03a550f54455af2894e43a1d8e586c4de6f55cb0 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 29 Nov 2018 09:31:10 +0100 Subject: [PATCH 264/719] update comment --- qcodes/dataset/data_set.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index face1f8302a..e2b714c485e 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -677,10 +677,11 @@ def add_parameter_values(self, spec: ParamSpec, values: VALUES): @staticmethod def _validate_parameters(*params: Union[str, ParamSpec, _BaseParameter] - ) -> List[str]: + ) -> List[str]: """ - validate the provided parameters have a name and return them as a list. - names. The Parameters may be a mix of strings, ParamSpecs or ordinary + Validate that the provided parameters have a name and return those + names as a list. + The Parameters may be a mix of strings, ParamSpecs or ordinary QCoDeS parameters. """ From af09c3728683b22619e76fc41e3ab7219a2c7302 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 10:15:04 +0100 Subject: [PATCH 265/719] Improve __repr__ string formatting --- qcodes/config/config.py | 6 +++--- qcodes/tests/test_config.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 1b1de22b53b..ab2e57bf7af 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -392,9 +392,9 @@ def __getattr__(self, name): def __repr__(self): old = super().__repr__() - output = f"""Current values: \n {current_config} \n - Current paths: \n {self._loaded_config_files} \n - {old}""" + output = (f"Current values: \n {self.current_config} \n" + f"Current paths: \n {self._loaded_config_files} \n" + f"{old}") return output diff --git a/qcodes/tests/test_config.py b/qcodes/tests/test_config.py index 0d39ed5b785..41afd621384 100644 --- a/qcodes/tests/test_config.py +++ b/qcodes/tests/test_config.py @@ -325,3 +325,14 @@ def test_update_from_path(path_to_config_file_on_disk): expected_path = os.path.join(path_to_config_file_on_disk, 'qcodesrc.json') assert cfg.current_config_path == expected_path + + +def test_repr(): + cfg = Config() + rep = cfg.__repr__() + + expected_rep = (f"Current values: \n {cfg.current_config} \n" + f"Current paths: \n {cfg._loaded_config_files} \n" + f"{super(Config, cfg).__repr__()}") + + assert rep == expected_rep From 71c3f8855be41ca9ed13bb6b76f7f5eee74d1073 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 10:16:29 +0100 Subject: [PATCH 266/719] Fix codacy issues --- qcodes/tests/dataset/dataset_fixtures.py | 2 +- qcodes/tests/dataset/test_dataset_basic.py | 8 ++++---- qcodes/tests/dataset/test_sqlite_base.py | 10 ++++------ 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index ca79a46a178..2e0d8d18b3e 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -3,7 +3,7 @@ from qcodes.dataset.param_spec import ParamSpec # pylint: disable=unused-import -from qcodes.tests.dataset.temporary_databases import dataset +from qcodes.tests.dataset.temporary_databases import dataset # pylint: enable=unused-import diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 2ffad6bd1ba..73cdb4bac46 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -633,10 +633,10 @@ def test_get_parameter_data(scalar_dataset): for i_param, param_name in enumerate(param_names): v_ref = row[i_param] v_test = dut[param_name][i_row] - if type(v_ref) == float: - assert type(v_test) == np.float64 - elif type(v_ref) == int: - assert type(v_test) == np.int + if isinstance(v_ref, float): + assert isinstance(v_test, np.float64) + elif isinstance(v_ref, int): + assert isinstance(v_test, np.int) else: raise RuntimeError('Unsupported data type') assert np.isclose(v_test, v_ref) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 7353a08c4f9..7e71e698b39 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -202,12 +202,10 @@ def test_get_parameter_data(scalar_dataset): for i_param, param_name in enumerate(params): v_ref = row[i_param] v_test = dut[param_name][i_row] - if type(v_ref) == float: - assert type(v_test) == np.float64 - elif type(v_ref) == int: - assert type(v_test) == np.int + if isinstance(v_ref, float): + assert isinstance(v_test, np.float64) + elif isinstance(v_ref, int): + assert isinstance(v_test, np.int) else: raise RuntimeError('Unsupported data type') assert np.isclose(v_test, v_ref) - - From d573602aef2097c41bda1d60333b6831b308e702 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 10:23:56 +0100 Subject: [PATCH 267/719] Update describe docstring --- qcodes/config/config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index ab2e57bf7af..70b2a4d7602 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -355,12 +355,13 @@ def save_to_cwd(self): self.save_config(self.cwd_file_name) self.save_schema(self.schema_cwd_file_name) - def describe(self, name): + def describe(self, name: str) -> str: """ Describe a configuration entry Args: - name (str): name of entry to describe + name: name of entry to describe in 'dotdict' notation, + e.g. name="user.scriptfolder" """ val = self.current_config sch = self.current_schema["properties"] From a697e24999ae28f3c613a7bb5662eb95f6854311 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 10:32:12 +0100 Subject: [PATCH 268/719] Add a test for add and describe --- qcodes/tests/test_config.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/qcodes/tests/test_config.py b/qcodes/tests/test_config.py index 41afd621384..01fcc7f2673 100644 --- a/qcodes/tests/test_config.py +++ b/qcodes/tests/test_config.py @@ -336,3 +336,27 @@ def test_repr(): f"{super(Config, cfg).__repr__()}") assert rep == expected_rep + + +def test_add_and_describe(): + """ + Test that a key an be added and described + """ + with default_config(): + + key = 'newkey' + value ='testvalue' + value_type ='string' + description ='A test' + default = 'testdefault' + + cfg = Config() + cfg.add(key=key, value=value, value_type=value_type, + description=description, default=default) + + + desc = cfg.describe(f'user.{key}') + expected_desc = (f"{description}.\nCurrent value: {value}. " + f"Type: {value_type}. Default: {default}.") + + assert desc == expected_desc From 6adeddd19de5a88ecabac7945f184a5864c712ca Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 11:09:55 +0100 Subject: [PATCH 269/719] add some more tests --- qcodes/tests/dataset/dataset_fixtures.py | 25 ++++++++++++++++++++++ qcodes/tests/dataset/test_dataset_basic.py | 16 ++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index 2e0d8d18b3e..d0525105cc3 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -2,6 +2,9 @@ import numpy as np from qcodes.dataset.param_spec import ParamSpec +from qcodes.dataset.measurements import Measurement +from qcodes.tests.instrument_mocks import ArraySetPointParam, Multi2DSetPointParam + # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import dataset # pylint: enable=unused-import @@ -29,3 +32,25 @@ def scalar_dataset(dataset): yield dataset +@pytest.fixture +def array_dataset(dataset): + meas = Measurement() + param = ArraySetPointParam() + meas.register_parameter(param) + + with meas.run() as datasaver: + datasaver.add_result((param, param.get(),)) + datasaver.dataset.conn.close() + yield dataset + + +@pytest.fixture +def multi_dataset(dataset): + meas = Measurement() + param = Multi2DSetPointParam() + meas.register_parameter(param) + + with meas.run() as datasaver: + datasaver.add_result((param, param.get(),)) + datasaver.dataset.conn.close() + yield dataset diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 73cdb4bac46..c38d18a278a 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -18,7 +18,7 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) -from qcodes.tests.dataset.dataset_fixtures import scalar_dataset +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, array_dataset, multi_dataset # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -617,8 +617,20 @@ def test_get_data_with_start_and_end_args(self, ds_with_vals, start, end, expected): assert expected == ds_with_vals.get_data(self.x, start=start, end=end) + def test_get_parameter_data(scalar_dataset): - ds = scalar_dataset + parameter_test_helper(scalar_dataset) + + +def test_get_array_parameter_data(array_dataset): + parameter_test_helper(array_dataset) + + +def test_get_array_parameter_data(multi_dataset): + parameter_test_helper(multi_dataset) + + +def parameter_test_helper(ds): params = ds.parameters.split(',') # delete some random parameter to test it with an incomplete list del params[-2] From 63723f55db5c61a84d1d671f405bdc879e61939f Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 29 Nov 2018 11:18:13 +0100 Subject: [PATCH 270/719] move error and make warning --- qcodes/dataset/data_set.py | 4 ---- qcodes/dataset/sqlite_base.py | 8 +++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index e2b714c485e..d3d21416eac 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -735,10 +735,6 @@ def get_data(self, string) """ valid_param_names = self._validate_parameters(*params) - if len(valid_param_names) == 0: - raise RuntimeError('Error calling `get_data`: you need to supply ' - 'at least one parameter for which to get the ' - 'data.') return get_data(self.conn, self.table_name, valid_param_names, start, end) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 981f160dc56..c5853925122 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -4,6 +4,7 @@ import sqlite3 import time import io +import warnings from typing import (Any, List, Optional, Tuple, Union, Dict, cast, Callable, Sequence, DefaultDict) import itertools @@ -1129,7 +1130,12 @@ def get_data(conn: SomeConnection, Returns: the data requested in the format of list of rows of values """ - + if len(columns) == 0: + warnings.warn( + 'get_data: requested data without specifying parameters/columns.' + 'Returning empyt list.' + ) + return [[]] query = _build_data_query(table_name, columns, start, end) c = atomic_transaction(conn, query) res = many_many(c, *columns) From de89df5aa18f62bb5998443fdb44e6d20e8eed14 Mon Sep 17 00:00:00 2001 From: Dominik Vogel Date: Thu, 29 Nov 2018 11:18:43 +0100 Subject: [PATCH 271/719] add test for empty columns --- qcodes/tests/dataset/test_sqlite_base.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 7e71e698b39..e1521914dd4 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -190,6 +190,12 @@ def test_runs_table_columns(empty_temp_db): assert colnames == [] +def test_get_data_no_columns(scalar_dataset): + ds = scalar_dataset + ref = mut.get_data(ds.conn, ds.table_name, []) + assert ref == [[]] + + def test_get_parameter_data(scalar_dataset): ds = scalar_dataset params = ds.parameters.split(',') From f75678e811ba4f6f8867892beb97d0a4a3abd80f Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 29 Nov 2018 12:37:25 +0100 Subject: [PATCH 272/719] Use pytest request.addfinalizer to avoid unclosed sqlite connections --- qcodes/tests/dataset/test_dataset_basic.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 52b28941bcd..9889223cb94 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -662,13 +662,15 @@ def test_get_description(some_paramspecs): assert loaded_ds.description == desc -def test_metadata(experiment): +def test_metadata(experiment, request): metadata1 = {'number': 1, "string": "Once upon a time..."} metadata2 = {'more': 'meta'} ds1 = DataSet(metadata=metadata1) + request.addfinalizer(ds1.conn.close) ds2 = DataSet(metadata=metadata2) + request.addfinalizer(ds2.conn.close) assert ds1.run_id == 1 assert ds1.metadata == metadata1 @@ -676,8 +678,10 @@ def test_metadata(experiment): assert ds2.metadata == metadata2 loaded_ds1 = DataSet(run_id=1) + request.addfinalizer(loaded_ds1.conn.close) assert loaded_ds1.metadata == metadata1 loaded_ds2 = DataSet(run_id=2) + request.addfinalizer(loaded_ds2.conn.close) assert loaded_ds2.metadata == metadata2 badtag = 'lex luthor' From 72706de1987c062dfc0d79b5f2ae250bdbd6061a Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 11:12:35 +0100 Subject: [PATCH 273/719] Add failing integration test --- .../dataset/test_database_extract_runs.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 9abe331d19d..3d9f8d47c52 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -16,6 +16,9 @@ from qcodes.tests.dataset.temporary_databases import two_empty_temp_db_connections from qcodes.tests.dataset.test_descriptions import some_paramspecs from qcodes.tests.dataset.test_database_creation_and_upgrading import error_caused_by +from qcodes.dataset.measurements import Measurement +from qcodes import Station +from qcodes.tests.instrument_mocks import DummyInstrument @contextmanager @@ -475,3 +478,38 @@ def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections, assert len(get_experiments(target_conn)) == 1 assert len(Experiment(exp_id=1, conn=target_conn)) == 5 + + +def test_integration_station_and_measurement(two_empty_temp_db_connections): + """ + An integration test where the runs in the source DB file are produced + with the Measurement object and there is a Station as well + """ + source_conn, target_conn = two_empty_temp_db_connections + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + source_exp = Experiment(conn=source_conn) + + # Set up measurement scenario + inst = DummyInstrument('inst', gates=['back', 'plunger', 'cutter']) + station = Station(inst) + + meas = Measurement(exp=source_exp, station=station) + meas.register_parameter(inst.back) + meas.register_parameter(inst.plunger) + meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) + + with meas.run() as datasaver: + for back_v in [1, 2, 3]: + for plung_v in [-3, -2.5, 0]: + datasaver.add_result((inst.back, back_v), + (inst.plunger, plung_v), + (inst.cutter, back_v+plung_v)) + + extract_runs_into_db(source_path, target_path, 1) + + target_ds = DataSet(conn=target_conn, run_id=1) + + assert datasaver.dataset.the_same_dataset_as(target_ds) + From 043f03cc8e24620c6200fa73e5667c8fc841600e Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 11:12:56 +0100 Subject: [PATCH 274/719] Remove dead line of code --- qcodes/dataset/database_extract_runs.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index d11d2bffade..87718208d79 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -180,8 +180,6 @@ def _extract_single_dataset_into_db(dataset: DataSet, parspecs = dataset.paramspecs.values() - #metadata = dataset.get_metadata() - _, target_run_id, target_table_name = create_run(target_conn, target_exp_id, name=dataset.name, @@ -198,8 +196,6 @@ def _extract_single_dataset_into_db(dataset: DataSet, dataset.completed_timestamp_raw) - - def _populate_results_table(source_conn: SomeConnection, target_conn: SomeConnection, source_table_name: str, From fd9d04654190f49c4e186513ecd9aaaf5a117792 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 12:27:32 +0100 Subject: [PATCH 275/719] Fix critical typo in test --- qcodes/tests/dataset/test_database_extract_runs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 3d9f8d47c52..4dc6a62487f 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -120,7 +120,7 @@ def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): assert len(target_exp) == length1 - target_dataset = DataSet(conn=source_conn, run_id=1) + target_dataset = DataSet(conn=target_conn, run_id=1) # Now make the interesting comparisons: are the target objects the same as # the source objects? From 4a2b8c89a9600c8e160cc24654159e83d679c4c1 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 12:29:13 +0100 Subject: [PATCH 276/719] Also extract metadata --- qcodes/dataset/database_extract_runs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 87718208d79..a10b15de554 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -179,12 +179,14 @@ def _extract_single_dataset_into_db(dataset: DataSet, return parspecs = dataset.paramspecs.values() + metadata = dataset.metadata _, target_run_id, target_table_name = create_run(target_conn, target_exp_id, name=dataset.name, guid=dataset.guid, - parameters=list(parspecs)) + parameters=list(parspecs), + metadata=metadata) _populate_results_table(source_conn, target_conn, dataset.table_name, From 3ac56777d3bb9c80febe2f6f2239b5007a7468ec Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:06:33 +0100 Subject: [PATCH 277/719] Refactor how snapshot get into dataset --- qcodes/dataset/data_set.py | 14 ++++++++++++++ qcodes/dataset/measurements.py | 6 ++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index ccdff6a17df..047e1466a82 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -518,6 +518,20 @@ def add_metadata(self, tag: str, metadata: Any): # `add_meta_data` does not commit, hence we commit here: self.conn.commit() + def add_snapshot(self, snapshot: str, overwrite: bool=False) -> None: + """ + Adds a snapshot to this run + + Args: + snapshot: the raw JSON dump of the snapshot + overwrite: force overwrite an existing snapshot + """ + if self.snapshot is None or overwrite: + add_meta_data(self.conn, self.run_id, {'snapshot': snapshot}) + elif self.snapshot is not None and not overwrite: + log.warning('This dataset already has a snapshot. Use overwrite' + '=True to overwrite that') + @property def started(self) -> bool: return self._started diff --git a/qcodes/dataset/measurements.py b/qcodes/dataset/measurements.py index 4e8e47baefb..130c3f2c7f1 100644 --- a/qcodes/dataset/measurements.py +++ b/qcodes/dataset/measurements.py @@ -465,10 +465,8 @@ def __enter__(self) -> DataSaver: station = self.station if station: - self.ds.add_metadata('snapshot', - json.dumps({'station': station.snapshot()}, - cls=NumpyJSONEncoder) - ) + self.ds.add_snapshot(json.dumps({'station': station.snapshot()}, + cls=NumpyJSONEncoder)) if self.parameters is not None: for paramspec in self.parameters.values(): From 9200cce80a3268ba8f06a04106f9010a28ccd5eb Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:07:06 +0100 Subject: [PATCH 278/719] Also extract snapshot --- qcodes/dataset/database_extract_runs.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index a10b15de554..8444d9c7f56 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -5,7 +5,8 @@ from qcodes.dataset.data_set import DataSet from qcodes.dataset.experiment_container import load_or_create_experiment -from qcodes.dataset.sqlite_base import (atomic, +from qcodes.dataset.sqlite_base import (add_meta_data, + atomic, connect, create_run, format_table_name, @@ -180,6 +181,7 @@ def _extract_single_dataset_into_db(dataset: DataSet, parspecs = dataset.paramspecs.values() metadata = dataset.metadata + snapshot_raw = dataset.snapshot_raw _, target_run_id, target_table_name = create_run(target_conn, target_exp_id, @@ -197,6 +199,9 @@ def _extract_single_dataset_into_db(dataset: DataSet, dataset.run_timestamp_raw, dataset.completed_timestamp_raw) + if snapshot_raw is not None: + add_meta_data(target_conn, target_run_id, {'snapshot': snapshot_raw}) + def _populate_results_table(source_conn: SomeConnection, target_conn: SomeConnection, From 965be0bc20647cf5640f610677879eb31ff40d3d Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:10:50 +0100 Subject: [PATCH 279/719] Add a station to the example notebook --- ...ing runs from one DB file to another.ipynb | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb b/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb index 56a164572cd..09772e7fdbc 100644 --- a/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb +++ b/docs/examples/DataSet/Extracting runs from one DB file to another.ipynb @@ -30,9 +30,10 @@ "\n", "from qcodes.dataset.sqlite_base import connect\n", "from qcodes.dataset.database_extract_runs import extract_runs_into_db\n", - "from qcodes.dataset.experiment_container import new_experiment, load_experiment_by_name\n", + "from qcodes.dataset.experiment_container import Experiment, load_experiment_by_name\n", "from qcodes.tests.instrument_mocks import DummyInstrument\n", - "from qcodes.dataset.measurements import Measurement" + "from qcodes.dataset.measurements import Measurement\n", + "from qcodes import Station" ] }, { @@ -49,7 +50,16 @@ "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Upgrading database: : 0it [00:00, ?it/s]\n", + "Upgrading database: : 0it [00:00, ?it/s]\n" + ] + } + ], "source": [ "source_conn = connect(source_path)\n", "target_conn = connect(target_path)" @@ -61,11 +71,12 @@ "metadata": {}, "outputs": [], "source": [ - "exp = new_experiment(name='extract_runs_experiment',\n", - " sample_name='no_sample',\n", - " conn=source_conn)\n", + "exp = Experiment(name='extract_runs_experiment',\n", + " sample_name='no_sample',\n", + " conn=source_conn)\n", "\n", - "my_inst = DummyInstrument('my_inst', gates=['voltage', 'current'])" + "my_inst = DummyInstrument('my_inst', gates=['voltage', 'current'])\n", + "station = Station(my_inst)" ] }, { @@ -175,7 +186,7 @@ { "data": { "text/plain": [ - "'aaaaaaaa-0c00-0007-0000-016754a23c83'" + "'aaaaaaaa-0c00-0007-0000-01675f5f9479'" ] }, "execution_count": 9, @@ -195,7 +206,7 @@ { "data": { "text/plain": [ - "'aaaaaaaa-0c00-0007-0000-016754a23c83'" + "'aaaaaaaa-0c00-0007-0000-01675f5f9479'" ] }, "execution_count": 10, @@ -206,13 +217,6 @@ "source": [ "target_exp.data_set(1).guid" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 7311b057d50ae25e32662650d86e4045a6b5f87c Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:15:22 +0100 Subject: [PATCH 280/719] Add version check of target DB file --- qcodes/dataset/database_extract_runs.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 8444d9c7f56..92a9b040131 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -1,5 +1,6 @@ from typing import Union from warnings import warn +import os import numpy as np @@ -26,7 +27,8 @@ def extract_runs_into_db(source_db_path: str, target_db_path: str, *run_ids: int, - upgrade_source_db: bool=False) -> None: + upgrade_source_db: bool=False, + upgrade_target_db: bool=False) -> None: """ Extract a selection of runs into another DB file. All runs must come from the same experiment. They will be added to an experiment with the same name @@ -49,6 +51,15 @@ def extract_runs_into_db(source_db_path: str, 'upgrade_source_db=True to auto-upgrade the source DB file.') return + if os.path.exists(target_db_path): + (t_v, new_v) = get_db_version_and_newest_available_version(target_db_path) + if t_v < new_v and not upgrade_target_db: + warn(f'Target DB version is {t_v}, but this function needs it to ' + f'be in version {new_v}. Run this function again with ' + 'upgrade_target_db=True to auto-upgrade the target DB file.') + return + + source_conn = connect(source_db_path) # Validate that all runs are in the source database From b0b731da57153d37f895ca95019b1094c207ee58 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:35:52 +0100 Subject: [PATCH 281/719] Make an error message more informative --- qcodes/dataset/database_extract_runs.py | 3 ++- qcodes/tests/dataset/test_database_extract_runs.py | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 92a9b040131..080b2c714fc 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -181,7 +181,8 @@ def _extract_single_dataset_into_db(dataset: DataSet, if not dataset.completed: raise ValueError('Dataset not completed. An incomplete dataset ' - 'can not be copied.') + 'can not be copied. The incomplete dataset has ' + f'GUID: {dataset.guid} and run_id: {dataset.run_id}') source_conn = dataset.conn diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 4dc6a62487f..d3c68394228 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -93,7 +93,10 @@ def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): extract_runs_into_db(source_path, target_path, source_dataset.run_id) assert error_caused_by(excinfo, ('Dataset not completed. An incomplete ' - 'dataset can not be copied.')) + 'dataset can not be copied. The ' + 'incomplete dataset has GUID: ' + f'{source_dataset.guid} and run_id: ' + f'{source_dataset.run_id}')) for ps in some_paramspecs[1].values(): source_dataset.add_parameter(ps) From c5d9bbb4c60cf342ea6a16c51b84e614f003ed27 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:37:23 +0100 Subject: [PATCH 282/719] Change the indentation in a docstring --- qcodes/dataset/sqlite_base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index fadaa6a3de3..146278c3540 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1285,14 +1285,14 @@ def get_runid_from_guid(conn: SomeConnection, guid: str) -> Union[int, None]: Get the run_id of a run based on the guid Args: - conn: connection to the database - guid: the guid to look up + conn: connection to the database + guid: the guid to look up Returns: The run_id if found, else -1. Raises: - RuntimeError if more than one run with the given GUID exists + RuntimeError if more than one run with the given GUID exists """ query = """ SELECT run_id From c813da9432167cc66843316434c1242cd06a8f17 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:40:06 +0100 Subject: [PATCH 283/719] Unindent a block --- qcodes/tests/dataset/test_dataset_basic.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 24f2460ecb2..88f13a23e7b 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -557,17 +557,17 @@ def test_metadata(experiment): def test_the_same_dataset_as(some_paramspecs, experiment): - paramspecs = some_paramspecs[2] - ds = DataSet() - ds.add_parameter(paramspecs['ps1']) - ds.add_parameter(paramspecs['ps2']) - ds.add_result({'ps1': 1, 'ps2': 2}) + paramspecs = some_paramspecs[2] + ds = DataSet() + ds.add_parameter(paramspecs['ps1']) + ds.add_parameter(paramspecs['ps2']) + ds.add_result({'ps1': 1, 'ps2': 2}) - same_ds_from_load = DataSet(run_id=ds.run_id) - assert ds.the_same_dataset_as(same_ds_from_load) + same_ds_from_load = DataSet(run_id=ds.run_id) + assert ds.the_same_dataset_as(same_ds_from_load) - new_ds = DataSet() - assert not ds.the_same_dataset_as(new_ds) + new_ds = DataSet() + assert not ds.the_same_dataset_as(new_ds) class TestGetData: From 08061c4e4c12a41ee69bd6eefafa51806c95212a Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:42:08 +0100 Subject: [PATCH 284/719] Fix indentation error --- qcodes/tests/dataset/test_dataset_loading.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_loading.py b/qcodes/tests/dataset/test_dataset_loading.py index 30ecaf5c866..823557f78c0 100644 --- a/qcodes/tests/dataset/test_dataset_loading.py +++ b/qcodes/tests/dataset/test_dataset_loading.py @@ -188,12 +188,12 @@ def test_get_data_by_id_order(dataset): @pytest.mark.usefixtures('experiment') def test_load_by_guid(some_paramspecs): - paramspecs = some_paramspecs[2] - ds = DataSet() - ds.add_parameter(paramspecs['ps1']) - ds.add_parameter(paramspecs['ps2']) - ds.add_result({'ps1': 1, 'ps2': 2}) + paramspecs = some_paramspecs[2] + ds = DataSet() + ds.add_parameter(paramspecs['ps1']) + ds.add_parameter(paramspecs['ps2']) + ds.add_result({'ps1': 1, 'ps2': 2}) - loaded_ds = load_by_guid(ds.guid) + loaded_ds = load_by_guid(ds.guid) - assert loaded_ds.the_same_dataset_as(ds) + assert loaded_ds.the_same_dataset_as(ds) From e20d4d099bc66d446ec30d7d08e2496b10ae86da Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:42:53 +0100 Subject: [PATCH 285/719] Remove print call --- qcodes/tests/dataset/test_sqlite_base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 60499421f2f..779f12244d9 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -195,7 +195,6 @@ def test_is_run_id_in_db(empty_temp_db): for _ in range(5): ds = DataSet(conn=conn, run_id=None) - print(ds.run_id) # there should now be run_ids 1, 2, 3, 4, 5 in the database good_ids = [1, 2, 3, 4, 5] From 18cbcea6aba3b0ea35cc104d552ece2356275881 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:45:14 +0100 Subject: [PATCH 286/719] Reword the docstring of a test --- qcodes/tests/dataset/test_database_extract_runs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index d3c68394228..701b8b01f76 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -38,8 +38,8 @@ def raise_if_file_changed(path_to_file: str): def test_missing_runs_raises(two_empty_temp_db_connections, some_paramspecs): """ - Test that an error is raised if runs not present in the source DB are - attempted extracted + Test that an error is raised if we attempt to extract a run not present in + the source DB """ source_conn, target_conn = two_empty_temp_db_connections From b3d2060339773a117857378c7a0cf39d6ce54b32 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:46:50 +0100 Subject: [PATCH 287/719] Assert some more --- qcodes/tests/dataset/test_database_extract_runs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 701b8b01f76..785a0acaeeb 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -116,6 +116,7 @@ def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs): target_exp = Experiment(conn=target_conn, exp_id=1) length1 = len(target_exp) + assert length1 == 1 # trying to insert the same run again should be a NOOP with raise_if_file_changed(target_path): From ea58bfd8527074231d04889974c6bada669530fd Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 13:48:09 +0100 Subject: [PATCH 288/719] Fix typo in a comment --- qcodes/tests/dataset/test_database_extract_runs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 785a0acaeeb..3bc084c9099 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -355,7 +355,7 @@ def test_result_table_naming_and_run_id(two_empty_temp_db_connections, extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id) # The target ds ought to have a runs table "customname-1-1" - # and ough to be the same dataset as its "ancestor" + # and ought to be the same dataset as its "ancestor" target_ds = DataSet(conn=target_conn, run_id=1) assert target_ds.table_name == "customname-1-1" From 47d93ac4c27ad9a6c90b6d80fb9feb9f38f1df16 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 13:54:21 +0100 Subject: [PATCH 289/719] Fix stupidly broken tests --- qcodes/tests/dataset/dataset_fixtures.py | 20 +++++++++++++------- qcodes/tests/dataset/test_dataset_basic.py | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index d0525105cc3..548bcac7ce4 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -6,7 +6,7 @@ from qcodes.tests.instrument_mocks import ArraySetPointParam, Multi2DSetPointParam # pylint: disable=unused-import -from qcodes.tests.dataset.temporary_databases import dataset +from qcodes.tests.dataset.temporary_databases import dataset, experiment # pylint: enable=unused-import @@ -33,24 +33,30 @@ def scalar_dataset(dataset): @pytest.fixture -def array_dataset(dataset): +def array_dataset(experiment): meas = Measurement() param = ArraySetPointParam() meas.register_parameter(param) with meas.run() as datasaver: datasaver.add_result((param, param.get(),)) - datasaver.dataset.conn.close() - yield dataset + try: + yield datasaver.dataset + finally: + datasaver.dataset.conn.close() + @pytest.fixture -def multi_dataset(dataset): +def multi_dataset(experiment): meas = Measurement() param = Multi2DSetPointParam() + meas.register_parameter(param) with meas.run() as datasaver: datasaver.add_result((param, param.get(),)) - datasaver.dataset.conn.close() - yield dataset + try: + yield datasaver.dataset + finally: + datasaver.dataset.conn.close() diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index c38d18a278a..52cb9b249db 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -626,7 +626,7 @@ def test_get_array_parameter_data(array_dataset): parameter_test_helper(array_dataset) -def test_get_array_parameter_data(multi_dataset): +def test_get_multi_parameter_data(multi_dataset): parameter_test_helper(multi_dataset) @@ -648,7 +648,7 @@ def parameter_test_helper(ds): if isinstance(v_ref, float): assert isinstance(v_test, np.float64) elif isinstance(v_ref, int): - assert isinstance(v_test, np.int) + assert isinstance(v_test, np.int32) else: raise RuntimeError('Unsupported data type') assert np.isclose(v_test, v_ref) From 150fdb0fa51e087fb3af0ee3ec8bb82fbd72250f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 14:04:18 +0100 Subject: [PATCH 290/719] This takes a connectionplus --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 126ac0dcde0..dc94c362a9e 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1182,7 +1182,7 @@ def get_data(conn: ConnectionPlus, return res -def get_parameter_data(conn: SomeConnection, +def get_parameter_data(conn: ConnectionPlus, table_name: str, columns: List[str], start: int = None, From 848373b89e2c263f9d7ef5283e3c2ee5c2c7b4cc Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 14:14:26 +0100 Subject: [PATCH 291/719] Replace SomeConnection with ConnectionPlus --- qcodes/dataset/data_set.py | 6 +++--- qcodes/dataset/database_extract_runs.py | 12 ++++++------ qcodes/dataset/experiment_container.py | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 940ab93e1d4..5c8bf052d2f 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -911,7 +911,7 @@ def __repr__(self) -> str: # public api -def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: +def load_by_id(run_id: int, conn: Optional[ConnectionPlus]=None) -> DataSet: """ Load dataset by run id @@ -934,7 +934,7 @@ def load_by_id(run_id: int, conn: Optional[SomeConnection]=None) -> DataSet: return d -def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: +def load_by_guid(guid: str, conn: Optional[ConnectionPlus]=None) -> DataSet: """ Load a dataset by its GUID @@ -964,7 +964,7 @@ def load_by_guid(guid: str, conn: Optional[SomeConnection]=None) -> DataSet: def load_by_counter(counter: int, exp_id: int, - conn: Optional[SomeConnection]=None) -> DataSet: + conn: Optional[ConnectionPlus]=None) -> DataSet: """ Load a dataset given its counter in a given experiment diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 080b2c714fc..1fe782c6c1e 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -21,7 +21,7 @@ mark_run_complete, new_experiment, select_many_where, - SomeConnection, + ConnectionPlus, sql_placeholder_string) @@ -123,7 +123,7 @@ def extract_runs_into_db(source_db_path: str, target_conn.close() -def _create_exp_if_needed(target_conn: SomeConnection, +def _create_exp_if_needed(target_conn: ConnectionPlus, exp_name: str, sample_name: str, fmt_str: str, @@ -161,7 +161,7 @@ def _create_exp_if_needed(target_conn: SomeConnection, def _extract_single_dataset_into_db(dataset: DataSet, - target_conn: SomeConnection, + target_conn: ConnectionPlus, target_exp_id: int) -> None: """ NB: This function should only be called from within @@ -215,8 +215,8 @@ def _extract_single_dataset_into_db(dataset: DataSet, add_meta_data(target_conn, target_run_id, {'snapshot': snapshot_raw}) -def _populate_results_table(source_conn: SomeConnection, - target_conn: SomeConnection, +def _populate_results_table(source_conn: ConnectionPlus, + target_conn: ConnectionPlus, source_table_name: str, target_table_name: str) -> None: """ @@ -242,7 +242,7 @@ def _populate_results_table(source_conn: SomeConnection, target_cursor.execute(insert_data_query, values) -def _rewrite_timestamps(target_conn: SomeConnection, target_run_id: int, +def _rewrite_timestamps(target_conn: ConnectionPlus, target_run_id: int, correct_run_timestamp: float, correct_completed_timestamp: float) -> None: """ diff --git a/qcodes/dataset/experiment_container.py b/qcodes/dataset/experiment_container.py index e3d56406407..5fc798cd264 100644 --- a/qcodes/dataset/experiment_container.py +++ b/qcodes/dataset/experiment_container.py @@ -14,7 +14,7 @@ get_experiment_name_from_experiment_id, get_runid_from_expid_and_counter, get_sample_name_from_experiment_id, - SomeConnection) + ConnectionPlus) from qcodes.dataset.sqlite_base import new_experiment as ne from qcodes.dataset.database import get_DB_location, get_DB_debug @@ -28,7 +28,7 @@ def __init__(self, path_to_db: Optional[str]=None, name: Optional[str]=None, sample_name: Optional[str]=None, format_string: str="{}-{}-{}", - conn: Optional[SomeConnection]=None) -> None: + conn: Optional[ConnectionPlus]=None) -> None: """ Create or load an experiment. If exp_id is None, a new experiment is created. If exp_id is not None, an experiment is loaded. @@ -204,7 +204,7 @@ def experiments()->List[Experiment]: def new_experiment(name: str, sample_name: str, format_string: Optional[str]="{}-{}-{}", - conn: Optional[SomeConnection]=None) -> Experiment: + conn: Optional[ConnectionPlus]=None) -> Experiment: """ Create a new experiment (in the database file from config) @@ -254,7 +254,7 @@ def load_last_experiment() -> Experiment: def load_experiment_by_name(name: str, sample: Optional[str] = None, - conn: Optional[SomeConnection]=None) -> Experiment: + conn: Optional[ConnectionPlus]=None) -> Experiment: """ Try to load experiment with the specified name. @@ -315,7 +315,7 @@ def load_experiment_by_name(name: str, def load_or_create_experiment(experiment_name: str, sample_name: Optional[str] = None, - conn: Optional[SomeConnection]=None)->Experiment: + conn: Optional[ConnectionPlus]=None)->Experiment: """ Find and return an experiment with the given name and sample name, or create one if not found. From a6d1ca3e4094e62fcf7427410bd006af982ea80f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 14:44:45 +0100 Subject: [PATCH 292/719] Fix tests on travis --- qcodes/tests/dataset/dataset_fixtures.py | 19 +++++++++++++++++++ qcodes/tests/dataset/test_dataset_basic.py | 13 +++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index 548bcac7ce4..89a9cfbd9d3 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -4,6 +4,7 @@ from qcodes.dataset.measurements import Measurement from qcodes.tests.instrument_mocks import ArraySetPointParam, Multi2DSetPointParam +from qcodes.instrument.parameter import Parameter # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import dataset, experiment @@ -60,3 +61,21 @@ def multi_dataset(experiment): yield datasaver.dataset finally: datasaver.dataset.conn.close() + +@pytest.fixture +def array_in_scalar_dataset(experiment): + meas = Measurement() + scalar_param = Parameter('scalarparam', set_cmd=None) + param = ArraySetPointParam() + meas.register_parameter(scalar_param) + meas.register_parameter(param, setpoints=(scalar_param,)) + + with meas.run() as datasaver: + for i in range(1, 10): + scalar_param.set(i) + datasaver.add_result((scalar_param, scalar_param.get()), + (param, param.get())) + try: + yield datasaver.dataset + finally: + datasaver.dataset.conn.close() diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index c230615ba2a..5bccd53a117 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -23,7 +23,7 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) -from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, array_dataset, multi_dataset +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, array_dataset, multi_dataset, array_in_scalar_dataset # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -770,6 +770,8 @@ def test_get_array_parameter_data(array_dataset): def test_get_multi_parameter_data(multi_dataset): parameter_test_helper(multi_dataset) +def test_get_array_in_scalar_param_data(array_in_scalar_dataset): + parameter_test_helper(array_in_scalar_dataset) def parameter_test_helper(ds): params = ds.parameters.split(',') @@ -782,6 +784,10 @@ def parameter_test_helper(ds): ref = ds.get_data(*params) dut = ds.get_parameter_data(*params) + column_lenghts = [] + for i_col, col in enumerate(dut): + column_lenghts.append(len(col)) + for i_row, row in enumerate(ref): for i_param, param_name in enumerate(param_names): v_ref = row[i_param] @@ -789,7 +795,10 @@ def parameter_test_helper(ds): if isinstance(v_ref, float): assert isinstance(v_test, np.float64) elif isinstance(v_ref, int): - assert isinstance(v_test, np.int32) + # default datatype for int is c_long which is 32 bit on + # windows and 64bit on linux + assert isinstance(v_test, np.int32) or \ + isinstance(v_test, np.int64) else: raise RuntimeError('Unsupported data type') assert np.isclose(v_test, v_ref) From 306a46eb3970ac9bdf60c5737d049a5303b392b3 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 14:53:52 +0100 Subject: [PATCH 293/719] Test that all columns have the same lenght --- qcodes/tests/dataset/test_dataset_basic.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 5bccd53a117..88cc59ad313 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -770,9 +770,11 @@ def test_get_array_parameter_data(array_dataset): def test_get_multi_parameter_data(multi_dataset): parameter_test_helper(multi_dataset) + def test_get_array_in_scalar_param_data(array_in_scalar_dataset): parameter_test_helper(array_in_scalar_dataset) + def parameter_test_helper(ds): params = ds.parameters.split(',') # delete some random parameter to test it with an incomplete list @@ -784,9 +786,11 @@ def parameter_test_helper(ds): ref = ds.get_data(*params) dut = ds.get_parameter_data(*params) - column_lenghts = [] - for i_col, col in enumerate(dut): - column_lenghts.append(len(col)) + column_lengths = [] + for col in dut.values(): + column_lengths.append(col.size) + column_lenghts = np.array(column_lengths) + assert np.all(column_lenghts == column_lenghts[0]) for i_row, row in enumerate(ref): for i_param, param_name in enumerate(param_names): From 8eadd1995f5af07d070fba26fe8aa62631a5eabc Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 15:03:36 +0100 Subject: [PATCH 294/719] Add test for old target db file --- .../dataset/test_database_extract_runs.py | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 3bc084c9099..9a3e8688e22 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -408,11 +408,13 @@ def test_load_by_X_functions(two_empty_temp_db_connections, assert source_ds_2_2.the_same_dataset_as(test_ds) -def test_old_versions_not_touched(two_empty_temp_db_connections): +def test_old_versions_not_touched(two_empty_temp_db_connections, + some_paramspecs): - _, target_conn = two_empty_temp_db_connections + source_conn, target_conn = two_empty_temp_db_connections target_path = path_to_dbfile(target_conn) + source_path = path_to_dbfile(source_conn) fixturepath = os.sep.join(qcodes.tests.dataset.__file__.split(os.sep)[:-1]) fixturepath = os.path.join(fixturepath, @@ -421,6 +423,9 @@ def test_old_versions_not_touched(two_empty_temp_db_connections): if not os.path.exists(fixturepath): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") + + # First test that we can not use an old version as source + with raise_if_file_changed(fixturepath): with pytest.warns(UserWarning) as warning: extract_runs_into_db(fixturepath, target_path, 1) @@ -431,6 +436,27 @@ def test_old_versions_not_touched(two_empty_temp_db_connections): 'the source DB file.') assert warning[0].message.args[0] == expected_mssg + # Then test that we can not use an old version as target + + # first create a run in the new version source + source_exp = Experiment(conn=source_conn) + source_ds = DataSet(conn=source_conn, exp_id=source_exp.exp_id) + + for ps in some_paramspecs[2].values(): + source_ds.add_parameter(ps) + source_ds.add_result({ps.name: 0.0 + for ps in some_paramspecs[2].values()}) + source_ds.mark_complete() + + with raise_if_file_changed(fixturepath): + with pytest.warns(UserWarning) as warning: + extract_runs_into_db(source_path, fixturepath, 1) + expected_mssg = ('Target DB version is 2, but this ' + 'function needs it to be in version 3. ' + 'Run this function again with ' + 'upgrade_target_db=True to auto-upgrade ' + 'the target DB file.') + assert warning[0].message.args[0] == expected_mssg def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections, some_paramspecs): From 5d7557e8d37677964d82dc1ee232612530450eb3 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 15:14:51 +0100 Subject: [PATCH 295/719] Add test for atomicity --- .../dataset/test_database_extract_runs.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 9a3e8688e22..935183728b8 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -2,6 +2,7 @@ from contextlib import contextmanager import re import os +from pathlib import Path import pytest import numpy as np @@ -543,3 +544,40 @@ def test_integration_station_and_measurement(two_empty_temp_db_connections): assert datasaver.dataset.the_same_dataset_as(target_ds) + +def test_atomicity(two_empty_temp_db_connections, some_paramspecs): + """ + Test the atomicity of the transaction by extracting and inserting two + runs where the second one is not completed. The not completed error must + roll back any changes to the target + """ + source_conn, target_conn = two_empty_temp_db_connections + + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + # The target file must exist for us to be able to see whether it has + # changed + Path(target_path).touch() + + source_exp = Experiment(conn=source_conn) + source_ds_1 = DataSet(conn=source_conn, exp_id=source_exp.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_1.add_parameter(ps) + source_ds_1.add_result({ps.name: 2.1 + for ps in some_paramspecs[2].values()}) + source_ds_1.mark_complete() + + source_ds_2 = DataSet(conn=source_conn, exp_id=source_exp.exp_id) + for ps in some_paramspecs[2].values(): + source_ds_2.add_parameter(ps) + source_ds_2.add_result({ps.name: 2.1 + for ps in some_paramspecs[2].values()}) + # This dataset is NOT marked as completed + + # now check that the target file is untouched + with raise_if_file_changed(target_path): + # although the not completed error is a ValueError, we get the + # RuntimeError from SQLite + with pytest.raises(RuntimeError): + extract_runs_into_db(source_path, target_path, 1, 2) From 6a7abfe6d2ea4b152351a96be073f95576aff315 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 29 Nov 2018 15:21:01 +0100 Subject: [PATCH 296/719] Add tests for datasets with strings --- qcodes/tests/dataset/dataset_fixtures.py | 19 +++++++++++++++++++ qcodes/tests/dataset/test_dataset_basic.py | 13 +++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index 89a9cfbd9d3..0493fb65840 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -79,3 +79,22 @@ def array_in_scalar_dataset(experiment): yield datasaver.dataset finally: datasaver.dataset.conn.close() + + +@pytest.fixture +def array_in_str_dataset(experiment): + meas = Measurement() + scalar_param = Parameter('scalarparam', set_cmd=None) + param = ArraySetPointParam() + meas.register_parameter(scalar_param, paramtype='text') + meas.register_parameter(param, setpoints=(scalar_param,)) + + with meas.run() as datasaver: + for i in ['A', 'B', 'C']: + scalar_param.set(i) + datasaver.add_result((scalar_param, scalar_param.get()), + (param, param.get())) + try: + yield datasaver.dataset + finally: + datasaver.dataset.conn.close() diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 88cc59ad313..ea81bb0dd12 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -23,7 +23,8 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) -from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, array_dataset, multi_dataset, array_in_scalar_dataset +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, \ + array_dataset, multi_dataset, array_in_scalar_dataset, array_in_str_dataset # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -775,6 +776,10 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset): parameter_test_helper(array_in_scalar_dataset) +def test_get_array_in_str_param_data(array_in_str_dataset): + parameter_test_helper(array_in_str_dataset) + + def parameter_test_helper(ds): params = ds.parameters.split(',') # delete some random parameter to test it with an incomplete list @@ -798,11 +803,15 @@ def parameter_test_helper(ds): v_test = dut[param_name][i_row] if isinstance(v_ref, float): assert isinstance(v_test, np.float64) + assert np.isclose(v_test, v_ref) elif isinstance(v_ref, int): # default datatype for int is c_long which is 32 bit on # windows and 64bit on linux assert isinstance(v_test, np.int32) or \ isinstance(v_test, np.int64) + assert np.isclose(v_test, v_ref) + elif isinstance(v_ref, str): + assert isinstance(v_test, np.str_) + assert v_ref == v_test else: raise RuntimeError('Unsupported data type') - assert np.isclose(v_test, v_ref) From c37c1fb8158715636eea66711c9fd5a8dde75279 Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Thu, 29 Nov 2018 15:23:04 +0100 Subject: [PATCH 297/719] Add test for column mismatch between target and source --- .../dataset/test_database_extract_runs.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index 935183728b8..c385920af69 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -581,3 +581,48 @@ def test_atomicity(two_empty_temp_db_connections, some_paramspecs): # RuntimeError from SQLite with pytest.raises(RuntimeError): extract_runs_into_db(source_path, target_path, 1, 2) + + +def test_column_mismatch(two_empty_temp_db_connections, some_paramspecs): + """ + Test insertion of runs with no metadata and no snapshot into a DB already + containing a run that has both + """ + + source_conn, target_conn = two_empty_temp_db_connections + source_path = path_to_dbfile(source_conn) + target_path = path_to_dbfile(target_conn) + + target_exp = Experiment(conn=target_conn) + + # Set up measurement scenario + inst = DummyInstrument('inst', gates=['back', 'plunger', 'cutter']) + station = Station(inst) + + meas = Measurement(exp=target_exp, station=station) + meas.register_parameter(inst.back) + meas.register_parameter(inst.plunger) + meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) + + with meas.run() as datasaver: + for back_v in [1, 2, 3]: + for plung_v in [-3, -2.5, 0]: + datasaver.add_result((inst.back, back_v), + (inst.plunger, plung_v), + (inst.cutter, back_v+plung_v)) + datasaver.dataset.add_metadata('meta_tag', 'meta_value') + + Experiment(conn=source_conn) + source_ds = DataSet(conn=source_conn) + for ps in some_paramspecs[2].values(): + source_ds.add_parameter(ps) + source_ds.add_result({ps.name: 2.1 + for ps in some_paramspecs[2].values()}) + source_ds.mark_complete() + + extract_runs_into_db(source_path, target_path, 1) + + # compare + target_copied_ds = DataSet(conn=target_conn, run_id=2) + + assert target_copied_ds.the_same_dataset_as(source_ds) From 114253de72e1d2da0779208ef441166281203666 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 29 Nov 2018 15:55:41 +0100 Subject: [PATCH 298/719] Use instrument fixture in tests to ensure instrument gets closed --- .../dataset/test_database_extract_runs.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/qcodes/tests/dataset/test_database_extract_runs.py b/qcodes/tests/dataset/test_database_extract_runs.py index c385920af69..ec44885bb29 100644 --- a/qcodes/tests/dataset/test_database_extract_runs.py +++ b/qcodes/tests/dataset/test_database_extract_runs.py @@ -37,6 +37,18 @@ def raise_if_file_changed(path_to_file: str): raise RuntimeError(f'File {path_to_file} was modified.') +@pytest.fixture(scope='function') +def inst(): + """ + Dummy instrument for testing, ensuring that it's instance gets closed + and removed from the global register of instruments, which, if not done, + make break other tests + """ + inst = DummyInstrument('inst', gates=['back', 'plunger', 'cutter']) + yield inst + inst.close() + + def test_missing_runs_raises(two_empty_temp_db_connections, some_paramspecs): """ Test that an error is raised if we attempt to extract a run not present in @@ -459,6 +471,7 @@ def test_old_versions_not_touched(two_empty_temp_db_connections, 'the target DB file.') assert warning[0].message.args[0] == expected_mssg + def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections, some_paramspecs): """ @@ -511,7 +524,8 @@ def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections, assert len(Experiment(exp_id=1, conn=target_conn)) == 5 -def test_integration_station_and_measurement(two_empty_temp_db_connections): +def test_integration_station_and_measurement(two_empty_temp_db_connections, + inst): """ An integration test where the runs in the source DB file are produced with the Measurement object and there is a Station as well @@ -523,7 +537,6 @@ def test_integration_station_and_measurement(two_empty_temp_db_connections): source_exp = Experiment(conn=source_conn) # Set up measurement scenario - inst = DummyInstrument('inst', gates=['back', 'plunger', 'cutter']) station = Station(inst) meas = Measurement(exp=source_exp, station=station) @@ -583,7 +596,7 @@ def test_atomicity(two_empty_temp_db_connections, some_paramspecs): extract_runs_into_db(source_path, target_path, 1, 2) -def test_column_mismatch(two_empty_temp_db_connections, some_paramspecs): +def test_column_mismatch(two_empty_temp_db_connections, some_paramspecs, inst): """ Test insertion of runs with no metadata and no snapshot into a DB already containing a run that has both @@ -596,7 +609,6 @@ def test_column_mismatch(two_empty_temp_db_connections, some_paramspecs): target_exp = Experiment(conn=target_conn) # Set up measurement scenario - inst = DummyInstrument('inst', gates=['back', 'plunger', 'cutter']) station = Station(inst) meas = Measurement(exp=target_exp, station=station) From 104dc2c83592a1bbf14baf88d62a273030ee987c Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 29 Nov 2018 18:18:29 +0100 Subject: [PATCH 299/719] Use log instead of print in AWG70000A driver Substitute the annoying `print` statements in the driver with `log.debug`. Logging can be easily enabled when needed, qcodes has convenient infrastructure as well. --- qcodes/instrument_drivers/tektronix/AWG70000A.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index 122d0388b1c..cf4762fd112 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -941,8 +941,7 @@ def make_SEQX_from_forged_sequence( # STEP 2: # Make all subsequence .sml files - print('Waveforms done') - print(wfmx_filenames) + log.debug(f'Waveforms done: {wfmx_filenames}') subseqsml_files: List[str] = [] subseqsml_filenames: List[str] = [] @@ -974,7 +973,7 @@ def make_SEQX_from_forged_sequence( subseqname = f'subsequence_{pos1}' - print(ss_wfm_names) + log.debug(f'Subsequence waveform names: {ss_wfm_names}') subseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], nreps=seqing['nrep'], @@ -1013,8 +1012,7 @@ def make_SEQX_from_forged_sequence( if f'wfm_{pos1}' in wn]) seqing = {k: [d[k] for d in seqings] for k in seqings[0].keys()} - print('True debug') - print(asset_names) + log.debug(f'Assets for SML file: {asset_names}') mainseqname = seqname mainseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], From 5eeed70d9ed60b0b7087519c201ce2b339fdc7dd Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 29 Nov 2018 09:32:11 -0800 Subject: [PATCH 300/719] removed superfluous newline --- .../QCodes example with Keithley S46.ipynb | 350 ++++++++++++++++++ qcodes/tests/drivers/test_keithley_s46.py | 1 - 2 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 docs/examples/driver_examples/QCodes example with Keithley S46.ipynb diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb new file mode 100644 index 00000000000..20ce0d8c4a0 --- /dev/null +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -0,0 +1,350 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.instrument_drivers.tektronix.Keithley_s46 import S46" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.36s\n" + ] + } + ], + "source": [ + "s46 = S46(\"s2\", \"GPIB0::7::INSTR\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'KEITHLEY INSTRUMENTS INC.,MODEL SYSTEM 46, 1327388, A03 '" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.ask(\"*IDN?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'6,6,6,6,0,0,0,0,1,0,0,1'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.ask(\":CONF:CPOL?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(@1,7)'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.ask(\":CLOS?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "26" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(s46.channels)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "channel1 is on relay A\n", + "channel2 is on relay A\n", + "channel3 is on relay A\n", + "channel4 is on relay A\n", + "channel5 is on relay A\n", + "channel6 is on relay A\n", + "channel7 is on relay B\n", + "channel8 is on relay B\n", + "channel9 is on relay B\n", + "channel10 is on relay B\n", + "channel11 is on relay B\n", + "channel12 is on relay B\n", + "channel13 is on relay C\n", + "channel14 is on relay C\n", + "channel15 is on relay C\n", + "channel16 is on relay C\n", + "channel17 is on relay C\n", + "channel18 is on relay C\n", + "channel19 is on relay D\n", + "channel20 is on relay D\n", + "channel21 is on relay D\n", + "channel22 is on relay D\n", + "channel23 is on relay D\n", + "channel24 is on relay D\n", + "channel25 is on relay 5\n", + "channel26 is on relay 8\n" + ] + } + ], + "source": [ + "for channel in s46.channels: \n", + " print(f\"{channel.short_name} is on relay {channel.relay_id}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'open'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.channels[0].state()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "s46.channels[0].state(\"close\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'close'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.channels[0].state()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Relay already in use by channel 1', 'setting s2_channel2_state to close')\n" + ] + } + ], + "source": [ + "try: \n", + " s46.channels[1].state(\"close\")\n", + " raise Exception(\"We should not be here \")\n", + "except RuntimeError as e: \n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "s46.channels[1].state(\"open\") # This should have no effect" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Relay already in use by channel 1', 'setting s2_channel6_state to close')\n" + ] + } + ], + "source": [ + "try: \n", + " s46.channels[5].state(\"close\")\n", + " raise Exception(\"We should not be here \")\n", + "except RuntimeError as e: \n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "s46.channels[6].state(\"close\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Relay already in use by channel 7', 'setting s2_channel8_state to close')\n" + ] + } + ], + "source": [ + "try: \n", + " s46.channels[7].state(\"close\")\n", + " raise Exception(\"We should not be here \")\n", + "except RuntimeError as e: \n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "s46.channels[0].state(\"open\")" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "s46.channels[1].state(\"close\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Relay already in use by channel 2', 'setting s2_channel1_state to close')\n" + ] + } + ], + "source": [ + "try: \n", + " s46.channels[0].state(\"close\")\n", + " raise Exception(\"We should not be here \")\n", + "except RuntimeError as e: \n", + " print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 13f29a400d0..5d90fa37b2d 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -46,7 +46,6 @@ def test_open_close(s46): s46.channels[0].state("open") s46.channels[1].state("close") - s46.channels[18].state("close") with pytest.raises( From 67ecfbe7ded55e9c6244d7ea47a45661ca0773f5 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 29 Nov 2018 17:52:53 -0800 Subject: [PATCH 301/719] major rewrite of driver: organized in terms of relays --- .../QCodes example with Keithley S46.ipynb | 230 ++++++------------ .../tektronix/Keithley_s46.py | 189 +++++++------- qcodes/tests/drivers/test_keithley_s46.py | 7 +- 3 files changed, 177 insertions(+), 249 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 20ce0d8c4a0..9d42179bd51 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -6,7 +6,7 @@ "metadata": {}, "outputs": [], "source": [ - "from qcodes.instrument_drivers.tektronix.Keithley_s46 import S46" + "from qcodes.instrument_drivers.tektronix.Keithley_s46 import S46, LockAcquisitionError" ] }, { @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.36s\n" + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.34s\n" ] } ], @@ -28,294 +28,222 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'KEITHLEY INSTRUMENTS INC.,MODEL SYSTEM 46, 1327388, A03 '" + "['A1']" ] }, - "execution_count": 13, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.ask(\"*IDN?\")" + "s46.get_closed_channels(by_name=True)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 4, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'6,6,6,6,0,0,0,0,1,0,0,1'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "s46.ask(\":CONF:CPOL?\")" + "s46.A1.state(\"open\")" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'(@1,7)'" + "'open'" ] }, - "execution_count": 15, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.ask(\":CLOS?\")" + "s46.A1.state()" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "s46.A1.state(\"close\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "26" + "'close'" ] }, - "execution_count": 3, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "len(s46.channels)" + "s46.A1.state()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "channel1 is on relay A\n", - "channel2 is on relay A\n", - "channel3 is on relay A\n", - "channel4 is on relay A\n", - "channel5 is on relay A\n", - "channel6 is on relay A\n", - "channel7 is on relay B\n", - "channel8 is on relay B\n", - "channel9 is on relay B\n", - "channel10 is on relay B\n", - "channel11 is on relay B\n", - "channel12 is on relay B\n", - "channel13 is on relay C\n", - "channel14 is on relay C\n", - "channel15 is on relay C\n", - "channel16 is on relay C\n", - "channel17 is on relay C\n", - "channel18 is on relay C\n", - "channel19 is on relay D\n", - "channel20 is on relay D\n", - "channel21 is on relay D\n", - "channel22 is on relay D\n", - "channel23 is on relay D\n", - "channel24 is on relay D\n", - "channel25 is on relay 5\n", - "channel26 is on relay 8\n" + "('Relay A is already in use by channel 1', 'setting s2_A2_state to close')\n" ] } ], "source": [ - "for channel in s46.channels: \n", - " print(f\"{channel.short_name} is on relay {channel.relay_id}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'open'" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s46.channels[0].state()" + "try: \n", + " s46.A2.state(\"close\")\n", + " raise(\"We should not be here\")\n", + "except LockAcquisitionError as e: \n", + " print(e)" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "s46.channels[0].state(\"close\")" + "s46.A1.state(\"open\")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'close'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "s46.channels[0].state()" + "s46.A2.state(\"close\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Relay already in use by channel 1', 'setting s2_channel2_state to close')\n" - ] - } - ], + "outputs": [], "source": [ - "try: \n", - " s46.channels[1].state(\"close\")\n", - " raise Exception(\"We should not be here \")\n", - "except RuntimeError as e: \n", - " print(e)" + "s46.A2.state(\"open\")" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ - "s46.channels[1].state(\"open\") # This should have no effect" + "assert s46.A1 is s46.channels[0]" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Relay already in use by channel 1', 'setting s2_channel6_state to close')\n" - ] - } - ], + "outputs": [], "source": [ - "try: \n", - " s46.channels[5].state(\"close\")\n", - " raise Exception(\"We should not be here \")\n", - "except RuntimeError as e: \n", - " print(e)" + "assert s46.A2 is s46.channels[1]" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "s46.channels[6].state(\"close\")" + "assert s46.B1 is s46.channels[6]" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Relay already in use by channel 7', 'setting s2_channel8_state to close')\n" - ] + "data": { + "text/plain": [ + "'B1'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "try: \n", - " s46.channels[7].state(\"close\")\n", - " raise Exception(\"We should not be here \")\n", - "except RuntimeError as e: \n", - " print(e)" + "s46.channels[6].short_name" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ - "s46.channels[0].state(\"open\")" + "s46.A1.state(\"close\")" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ - "s46.channels[1].state(\"close\")" + "s46.B1.state(\"close\")" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Relay already in use by channel 2', 'setting s2_channel1_state to close')\n" - ] + "data": { + "text/plain": [ + "['A1', 'B1']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "try: \n", - " s46.channels[0].state(\"close\")\n", - " raise Exception(\"We should not be here \")\n", - "except RuntimeError as e: \n", - " print(e)" + "s46.get_closed_channels(by_name=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "s46.R8.state(\"close\")" ] }, { diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 4c2acdb4b04..29bf91a4191 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -1,146 +1,149 @@ import numpy as np -import itertools -from collections import defaultdict import re +from typing import cast from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum -class ChannelNotPresentError(Exception): - pass - - class LockAcquisitionError(Exception): pass -class RelayLock: - def __init__(self): - self._acquired = False - self._acquired_by = None - - def acquire(self, requester_id): - if self._acquired and self._acquired_by != requester_id: - raise LockAcquisitionError( - f"Relay already in use by channel {self.acquired_by}" - ) - - self._acquired = True - self._acquired_by = requester_id - - def release(self, requester_id): - if self._acquired_by != requester_id: - # It should be impossible to get here. There is a driver bug - # if we do. - raise RuntimeError( - f"Relay can only be freed by channel {self.acquired_by} " - f"that acquired the lock. Please get in touch with a QCoDeS " - f"developer to get to the root cause of this error" - ) - - self._acquired = False - self._acquired_by = None - - @property - def acquired_by(self): - return self._acquired_by - - -class RFSwitchChannel(InstrumentChannel): - def __init__(self, parent, name, channel_number, relay_locks): +class S46Channel(InstrumentChannel): + def __init__(self, parent, name, channel_number, relay): super().__init__(parent, name) - self._channel_number = channel_number - - self._relay_id = self._get_relay() - self._relay_lock = relay_locks[self._relay_id] + self._channel_number = channel_number + self._relay = relay if self._get_state() == "close": try: - self._relay_lock.acquire(self._channel_number) + self._relay.acquire_lock(self._channel_number) except LockAcquisitionError as e: raise RuntimeError( "The driver is initialized from an undesirable instrument " "state where more then one channel on a single relay is " - "closed. It is advised to power cycle the instrument or to " - "manually send the 'OPEN:ALL' SCPI command to get the " - "instrument back into a normal state. Refusing to " - "initialize driver!" + "closed. It is advised to power cycle the instrument. " + "Refusing to initialize driver!" ) from e self.add_parameter( "state", get_cmd=self._get_state, - set_cmd=f":{{}} (@{self._channel_number})", - set_parser=self._set_state_parser, + set_cmd=self._set_state, vals=Enum("open", "close") ) - def _get_relay(self): - relay_layout = self.parent.relay_layout - found = False + def _get_state(self): + is_closed = self._channel_number in \ + self.root_instrument.get_closed_channels() - count = 0 - for count, total_count in enumerate(np.cumsum(relay_layout)): - if total_count >= self._channel_number: - found = True - break + return {True: "close", False: "open"}[is_closed] - if not found: - raise ChannelNotPresentError() + def _set_state(self, new_state: str): - return (["A", "B", "C", "D"] + [str(i) for i in range(1, 9)])[count] + current_state = self._get_state() + if new_state == current_state: + return - def _get_state(self): - closed_channels = re.findall(r"(\d+)[,)]", self.ask(":CLOS?")) - return "close" \ - if str(self._channel_number) in closed_channels \ - else "open" + if new_state == "close": + self._relay.acquire_lock(self._channel_number) + elif new_state == "open": + self._relay.release_lock(self._channel_number) - def _set_state_parser(self, new_state: str): + self.write(f":{new_state} (@{self._channel_number})") - if new_state == "close": - self._relay_lock.acquire(self._channel_number) - elif new_state == "open" \ - and self._relay_lock.acquired_by == self._channel_number: - self._relay_lock.release(self._channel_number) +class S46Relay(InstrumentChannel): + def __init__(self, parent, name, channel_offset, channel_count): + super().__init__(parent, name) - return new_state.upper() + self._channel_offset = channel_offset + self._locked_by = None - @property - def relay_id(self): - return self._relay_id + channels = ChannelList( + cast(VisaInstrument, self), + "channel", + S46Channel, + snapshotable=False + ) + + for count, channel_number in enumerate(range( + channel_offset, channel_offset + channel_count)): + + if channel_count == 1: + channel_name = self.short_name + else: + channel_name = f"{self.short_name}{count + 1}" + + channel = S46Channel( + cast(VisaInstrument, self.parent), + channel_name, + channel_number + 1, + self + ) + channels.append(channel) + + self.add_submodule("channels", channels) + + def acquire_lock(self, channel_number): + if self._locked_by is None: + self._locked_by = channel_number + else: + raise LockAcquisitionError( + f"Relay {self.short_name} is already in use by channel " + f"{self._locked_by}" + ) + + def release_lock(self, channel_number): + if self._locked_by == channel_number: + self._locked_by = None + else: + raise RuntimeError( + "This run time error should never occur. Please get in touch " + "with a QCoDeS developer" + ) class S46(VisaInstrument): def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) - self._relay_layout = [ + relay_layout = [ int(i) for i in self.ask(":CONF:CPOL?").split(",") ] + relay_names = (["A", "B", "C", "D"] + [f"R{i}" for i in range(1, 9)]) + # Relay offsets are independent of pole configuration. See page + # 2-5 of the manual + channel_offsets = np.cumsum([0] + 4 * [6] + 7 * [1]) channels = ChannelList( - self, "channel", RFSwitchChannel, snapshotable=False + self, + "channel", + S46Channel, + snapshotable=False ) - relay_locks = defaultdict(RelayLock) - - for chn in itertools.count(1): - chn_name = f"channel{chn}" + for name, channel_offset, channel_count in zip( + relay_names, channel_offsets, relay_layout): - try: - channel = RFSwitchChannel(self, chn_name, chn, relay_locks) - except ChannelNotPresentError: - break - - self.add_submodule(chn_name, channel) - channels.append(channel) + relay = S46Relay(self, name, channel_offset, channel_count) + for channel in relay.channels: + channels.append(channel) + self.add_submodule(channel.short_name, channel) self.add_submodule("channels", channels) self.connect_message() - @property - def relay_layout(self): - return self._relay_layout + def get_closed_channels(self, by_name=False): + + closed_channels_str = re.findall(r"\d+", self.ask(":CLOS?")) + closed_channels_numbers = [int(i) for i in closed_channels_str] + + if not by_name: + return closed_channels_numbers + else: + return [ + self.channels[i-1].short_name + for i in closed_channels_numbers + ] diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 5d90fa37b2d..2f2a7e43a0e 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -32,8 +32,8 @@ def test_init(s46): closed_channels = [0, 7, 12] for channel_nr in range(n_channels): - assert s46.channels[channel_nr].state() == "close" \ - if channel_nr in closed_channels else "open" + state = "close" if channel_nr in closed_channels else "open" + assert s46.channels[channel_nr].state() == state def test_open_close(s46): @@ -53,6 +53,3 @@ def test_open_close(s46): match="Relay already in use by channel" ): s46.channels[19].state("close") - - s46.channels[18].state("open") - s46.channels[19].state("close") From af646aec542a289a4010bb8b28fe704552a20da2 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 29 Nov 2018 18:47:33 -0800 Subject: [PATCH 302/719] do not raise a run time warning when attempting to release a lock that does not belong to you --- .../QCodes example with Keithley S46.ipynb | 72 ++++++++++++------- .../tektronix/Keithley_s46.py | 50 +++++++------ 2 files changed, 70 insertions(+), 52 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 9d42179bd51..05698e3beb9 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.34s\n" + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.36s\n" ] } ], @@ -34,7 +34,9 @@ { "data": { "text/plain": [ - "['A1']" + "[,\n", + " ,\n", + " ]" ] }, "execution_count": 3, @@ -43,13 +45,33 @@ } ], "source": [ - "s46.get_closed_channels(by_name=True)" + "s46.get_closed_channels()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "26" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(s46.channels)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, "outputs": [], "source": [ "s46.A1.state(\"open\")" @@ -57,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -66,7 +88,7 @@ "'open'" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -77,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -86,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -95,7 +117,7 @@ "'close'" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -106,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -127,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -136,7 +158,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -145,7 +167,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -221,20 +243,9 @@ "cell_type": "code", "execution_count": 19, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A1', 'B1']" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "s46.get_closed_channels(by_name=True)" + "s46.R8.state(\"close\")" ] }, { @@ -243,7 +254,16 @@ "metadata": {}, "outputs": [], "source": [ - "s46.R8.state(\"close\")" + "s46.open_all_channels()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "s46.A1.state(\"open\")" ] }, { diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 29bf91a4191..e61ac3fd8ba 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -36,16 +36,12 @@ def __init__(self, parent, name, channel_number, relay): def _get_state(self): is_closed = self._channel_number in \ - self.root_instrument.get_closed_channels() + self.root_instrument.get_closed_channel_numbers() return {True: "close", False: "open"}[is_closed] def _set_state(self, new_state: str): - current_state = self._get_state() - if new_state == current_state: - return - if new_state == "close": self._relay.acquire_lock(self._channel_number) elif new_state == "open": @@ -53,6 +49,10 @@ def _set_state(self, new_state: str): self.write(f":{new_state} (@{self._channel_number})") + @property + def channel_number(self): + return self._channel_number + class S46Relay(InstrumentChannel): def __init__(self, parent, name, channel_offset, channel_count): @@ -79,7 +79,7 @@ def __init__(self, parent, name, channel_offset, channel_count): channel = S46Channel( cast(VisaInstrument, self.parent), channel_name, - channel_number + 1, + channel_number, self ) channels.append(channel) @@ -87,22 +87,19 @@ def __init__(self, parent, name, channel_offset, channel_count): self.add_submodule("channels", channels) def acquire_lock(self, channel_number): - if self._locked_by is None: - self._locked_by = channel_number - else: + + if self._locked_by is not None and self._locked_by != channel_number: raise LockAcquisitionError( f"Relay {self.short_name} is already in use by channel " f"{self._locked_by}" ) + else: + self._locked_by = channel_number def release_lock(self, channel_number): + if self._locked_by == channel_number: self._locked_by = None - else: - raise RuntimeError( - "This run time error should never occur. Please get in touch " - "with a QCoDeS developer" - ) class S46(VisaInstrument): @@ -113,9 +110,9 @@ def __init__(self, name, address, **kwargs): int(i) for i in self.ask(":CONF:CPOL?").split(",") ] relay_names = (["A", "B", "C", "D"] + [f"R{i}" for i in range(1, 9)]) - # Relay offsets are independent of pole configuration. See page + # Channel offsets are independent of pole configuration. See page # 2-5 of the manual - channel_offsets = np.cumsum([0] + 4 * [6] + 7 * [1]) + channel_offsets = np.cumsum([0] + 4 * [6] + 7 * [1]) + 1 channels = ChannelList( self, @@ -135,15 +132,16 @@ def __init__(self, name, address, **kwargs): self.add_submodule("channels", channels) self.connect_message() - def get_closed_channels(self, by_name=False): - + def get_closed_channel_numbers(self): closed_channels_str = re.findall(r"\d+", self.ask(":CLOS?")) - closed_channels_numbers = [int(i) for i in closed_channels_str] + return [int(i) for i in closed_channels_str] - if not by_name: - return closed_channels_numbers - else: - return [ - self.channels[i-1].short_name - for i in closed_channels_numbers - ] + def get_closed_channels(self): + return [ + channel for channel in self.channels if + channel.channel_number in self.get_closed_channel_numbers() + ] + + def open_all_channels(self): + for channel in self.get_closed_channels(): + cast(S46Channel, channel).state("open") From ff28261ef72a247dc94483edddc78da3ee897464 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 30 Nov 2018 11:40:45 +0100 Subject: [PATCH 303/719] Use instance log instead of module level log.<> --> self.log.<> --- .../instrument_drivers/tektronix/AWG70000A.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index cf4762fd112..aa91b0a514d 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -658,12 +658,12 @@ def _sendBinaryFile(self, binfile: bytes, filename: str, self.current_directory(path) if overwrite: - log.debug(f'Pre-deleting file {filename} at {path}') + self.log.debug(f'Pre-deleting file {filename} at {path}') self.visa_handle.write(f'MMEMory:DELete "{filename}"') # if the file does not exist, # an error code -256 is put in the error queue resp = self.visa_handle.query(f'SYSTem:ERRor:CODE?') - log.debug(f'Pre-deletion finished with return code {resp}') + self.log.debug(f'Pre-deletion finished with return code {resp}') self.visa_handle.write_raw(msg) @@ -839,12 +839,12 @@ def _makeWFMXFileBinaryData(data: np.ndarray, amplitude: float) -> bytes: binary_marker = struct.pack(fmt, *markers) if wfm.max() > channel_max or wfm.min() < channel_min: - log.warning('Waveform exceeds specified channel range.' - ' The resulting waveform will be clipped. ' - 'Waveform min.: {} (V), waveform max.: {} (V),' - 'Channel min.: {} (V), channel max.: {} (V)' - ''.format(wfm.min(), wfm.max(), channel_min, - channel_max)) + self.log.warning('Waveform exceeds specified channel range.' + ' The resulting waveform will be clipped. ' + 'Waveform min.: {} (V), waveform max.: {} (V),' + 'Channel min.: {} (V), channel max.: {} (V)' + ''.format(wfm.min(), wfm.max(), channel_min, + channel_max)) # the data must be such that channel_max becomes 1 and # channel_min becomes -1 @@ -941,7 +941,7 @@ def make_SEQX_from_forged_sequence( # STEP 2: # Make all subsequence .sml files - log.debug(f'Waveforms done: {wfmx_filenames}') + self.log.debug(f'Waveforms done: {wfmx_filenames}') subseqsml_files: List[str] = [] subseqsml_filenames: List[str] = [] @@ -973,7 +973,7 @@ def make_SEQX_from_forged_sequence( subseqname = f'subsequence_{pos1}' - log.debug(f'Subsequence waveform names: {ss_wfm_names}') + self.log.debug(f'Subsequence waveform names: {ss_wfm_names}') subseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], nreps=seqing['nrep'], @@ -1012,7 +1012,7 @@ def make_SEQX_from_forged_sequence( if f'wfm_{pos1}' in wn]) seqing = {k: [d[k] for d in seqings] for k in seqings[0].keys()} - log.debug(f'Assets for SML file: {asset_names}') + self.log.debug(f'Assets for SML file: {asset_names}') mainseqname = seqname mainseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], From 8cb21a8bbe69e41895234b4d11a1d88ee74869ea Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Fri, 30 Nov 2018 12:09:25 +0100 Subject: [PATCH 304/719] In static methods use log of the module level --- .../instrument_drivers/tektronix/AWG70000A.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/AWG70000A.py b/qcodes/instrument_drivers/tektronix/AWG70000A.py index aa91b0a514d..e23953c4f6a 100644 --- a/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -839,12 +839,12 @@ def _makeWFMXFileBinaryData(data: np.ndarray, amplitude: float) -> bytes: binary_marker = struct.pack(fmt, *markers) if wfm.max() > channel_max or wfm.min() < channel_min: - self.log.warning('Waveform exceeds specified channel range.' - ' The resulting waveform will be clipped. ' - 'Waveform min.: {} (V), waveform max.: {} (V),' - 'Channel min.: {} (V), channel max.: {} (V)' - ''.format(wfm.min(), wfm.max(), channel_min, - channel_max)) + log.warning('Waveform exceeds specified channel range.' + ' The resulting waveform will be clipped. ' + 'Waveform min.: {} (V), waveform max.: {} (V),' + 'Channel min.: {} (V), channel max.: {} (V)' + ''.format(wfm.min(), wfm.max(), channel_min, + channel_max)) # the data must be such that channel_max becomes 1 and # channel_min becomes -1 @@ -941,7 +941,7 @@ def make_SEQX_from_forged_sequence( # STEP 2: # Make all subsequence .sml files - self.log.debug(f'Waveforms done: {wfmx_filenames}') + log.debug(f'Waveforms done: {wfmx_filenames}') subseqsml_files: List[str] = [] subseqsml_filenames: List[str] = [] @@ -973,7 +973,7 @@ def make_SEQX_from_forged_sequence( subseqname = f'subsequence_{pos1}' - self.log.debug(f'Subsequence waveform names: {ss_wfm_names}') + log.debug(f'Subsequence waveform names: {ss_wfm_names}') subseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], nreps=seqing['nrep'], @@ -1012,7 +1012,7 @@ def make_SEQX_from_forged_sequence( if f'wfm_{pos1}' in wn]) seqing = {k: [d[k] for d in seqings] for k in seqings[0].keys()} - self.log.debug(f'Assets for SML file: {asset_names}') + log.debug(f'Assets for SML file: {asset_names}') mainseqname = seqname mainseqsml = AWG70000A._makeSMLFile(trig_waits=seqing['twait'], From 7c07882184e39d67202234f913e7b849023d1d50 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 30 Nov 2018 15:52:56 +0100 Subject: [PATCH 305/719] Add get data function that expands arrays --- qcodes/dataset/sqlite_base.py | 80 ++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index dc94c362a9e..f15ba935a5a 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1312,7 +1312,7 @@ def get_layout(conn: ConnectionPlus, Args: conn: The database connection - run_id: The run_id as in the runs table + layout_id: The run_id as in the layouts table Returns: A dict with name, label, and unit @@ -1390,9 +1390,87 @@ def get_dependencies(conn: ConnectionPlus, res = many_many(c, 'independent', 'axis_num') return res + +def get_independent_parameters(conn: ConnectionPlus, + run_id: int): + """" + This should return all parameters that are neither + dependent on other parameters or dependencies of other parameters + """ + raise NotADirectoryError("TODO") # Higher level Wrappers +def get_dependency_parameters(conn: ConnectionPlus, param: str, + run_id: int) -> List[ParamSpec]: + """ + Given a parameter name return its ParamSpec of the parameter along with + the ParamSpecs of all it's dependencies. + + Args: + conn: + param: + run_id: + + """ + layout_id = get_layout_id(conn, param, run_id) + deps = get_dependencies(conn, layout_id) + parameters = [get_paramspec(conn, run_id, param)] + + for dep in deps: + depinfo = get_layout(conn, dep[0]) + parameters.append(get_paramspec(conn, run_id, depinfo['name'])) + return parameters + + +def get_data_of_param_and_deps_as_columns(conn: ConnectionPlus, + params: List[str], run_id: int): + """ + Load + Args: + conn: + params: + run_id: + + Returns: + + """ + output = {} + if len(params) == 0: + raise NotImplementedError("HERE we should look up all " + "dependent standalone parameters") + + for param in params: + params = get_dependency_parameters(conn, param, run_id) + columns = [param.name for param in params] + types = [param.type for param in params] + # !!! fix this, there should probably be a method to get the table + # from the run_id + sql = f""" + SELECT result_table_name FROM runs WHERE run_id = {run_id} + """ + c = conn.execute(sql) + result_table_name = one(c, 'result_table_name') + + res = get_data(conn, result_table_name, columns) + + if 'array' in types and 'numeric' in types: # todo handle str + # todo: Should we check that all the arrays are the same size? + first_array_element = types.index('array') + non_array_elements = [i for i, x in enumerate(types) + if x == "numeric"] + for dat in res: + for element in non_array_elements: + dat[element] = np.zeros_like(dat[first_array_element]) \ + + dat[element] + + res_t = list(map(list, zip(*res))) + output[param] = {name: np.array(column_data) + for name, column_data + in zip(columns, res_t)} + return output + + def new_experiment(conn: ConnectionPlus, name: str, sample_name: str, From 2b5f06fdc093fe9d7adfbe1bd2bf994e59edb595 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 30 Nov 2018 16:16:08 +0100 Subject: [PATCH 306/719] make syntax match other funcs better --- qcodes/dataset/sqlite_base.py | 43 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index f15ba935a5a..792e21ca5d4 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1424,35 +1424,42 @@ def get_dependency_parameters(conn: ConnectionPlus, param: str, def get_data_of_param_and_deps_as_columns(conn: ConnectionPlus, - params: List[str], run_id: int): + table_name: str, + columns: List[str], + start: Optional[int]=None, + end: Optional[int]=None) -> \ + Dict[str, Dict[str, np.ndarray]]: """ - Load - Args: - conn: - params: - run_id: - - Returns: + Get data for one or more parameters and its dependencies. The data + is returned as numpy arrays nested 2 layers of dicts. The keys or the + outermost are the requested parameters and the second level by the loaded + parameters. + Args: + conn: database connection + table_name: name of the table + columns: list of columns + start: start of range; if None, then starts from the top of the table + end: end of range; if None, then ends at the bottom of the table """ output = {} - if len(params) == 0: + if len(columns) == 0: raise NotImplementedError("HERE we should look up all " "dependent standalone parameters") - for param in params: + # get run_id + sql = """ + SELECT run_id FROM runs WHERE result_table_name = ? + """ + c = atomic_transaction(conn, sql, table_name) + run_id = one(c, 'run_id') + + for param in columns: params = get_dependency_parameters(conn, param, run_id) columns = [param.name for param in params] types = [param.type for param in params] - # !!! fix this, there should probably be a method to get the table - # from the run_id - sql = f""" - SELECT result_table_name FROM runs WHERE run_id = {run_id} - """ - c = conn.execute(sql) - result_table_name = one(c, 'result_table_name') - res = get_data(conn, result_table_name, columns) + res = get_data(conn, table_name, columns, start=start, end=end) if 'array' in types and 'numeric' in types: # todo handle str # todo: Should we check that all the arrays are the same size? From 4a11e76f934519f3704d2782fcbe382811f142e8 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 30 Nov 2018 16:16:30 +0100 Subject: [PATCH 307/719] Add dataset wrapper --- qcodes/dataset/data_set.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 56a466e15de..b80e4ebcf55 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -37,7 +37,8 @@ update_run_description, run_exists, remove_trigger, make_connection_plus_from, - ConnectionPlus) + ConnectionPlus, + get_data_of_param_and_deps_as_columns) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -782,6 +783,18 @@ def get_parameter_data( return get_parameter_data(self.conn, self.table_name, valid_param_names, start, end) + def get_data_of_param_and_deps_as_columns( + self, + *params: Union[str, ParamSpec, _BaseParameter], + start: Optional[int] = None, + end: Optional[int] = None) -> Dict[str, Dict[str, numpy.ndarray]]: + valid_param_names = self._validate_parameters(*params) + return get_data_of_param_and_deps_as_columns(self.conn, + self.table_name, + valid_param_names, + start, end) + + def get_values(self, param_name: str) -> List[List[Any]]: """ Get the values (i.e. not NULLs) of the specified parameter From 1d5c9b95d81ba050d26129901088bb2bf76d7419 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Fri, 30 Nov 2018 15:05:51 -0800 Subject: [PATCH 308/719] major rewrite, again --- .../QCodes example with Keithley S46.ipynb | 206 +++++++++++++++++- .../tektronix/Keithley_s46.py | 94 ++++---- qcodes/tests/drivers/test_keithley_s46.py | 22 +- 3 files changed, 266 insertions(+), 56 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 05698e3beb9..6405988ca0a 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -11,14 +11,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.36s\n" + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.20s\n" ] } ], @@ -266,6 +266,206 @@ "s46.A1.state(\"open\")" ] }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'A1': 1, 'A2': 2, 'A3': 3, 'A4': 4, 'A5': 5, 'A6': 6, 'B1': 7, 'B2': 8, 'B3': 9, 'B4': 10, 'B5': 11, 'B6': 12, 'C1': 13, 'C2': 14, 'C3': 15, 'C4': 16, 'C5': 17, 'C6': 18, 'D1': 19, 'D2': 20, 'D3': 21, 'D4': 22, 'D5': 23, 'D6': 24, 'R1': 25, 'R2': 26, 'R3': 27, 'R4': 28, 'R5': 29, 'R6': 30, 'R7': 31, 'R8': 32}\n" + ] + } + ], + "source": [ + "channel_aliases = [\n", + " f\"{relay_name}{index}\" for\n", + " relay_name, index in product(\n", + " [\"A\", \"B\", \"C\", \"D\"],\n", + " range(1, 7)\n", + " )\n", + "]\n", + "channel_aliases += [f\"R{i}\" for i in range(1, 9)]\n", + "\n", + "print(dict(zip(channel_aliases, range(1, 33))))" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'A1': 1,\n", + " 'A2': 2,\n", + " 'A3': 3,\n", + " 'A4': 4,\n", + " 'A5': 5,\n", + " 'A6': 6,\n", + " 'B1': 7,\n", + " 'B2': 8,\n", + " 'B3': 9,\n", + " 'B4': 10,\n", + " 'B5': 11,\n", + " 'B6': 12,\n", + " 'C1': 13,\n", + " 'C2': 14,\n", + " 'C3': 15,\n", + " 'C4': 16,\n", + " 'C5': 17,\n", + " 'C6': 18,\n", + " 'D1': 19,\n", + " 'D2': 20,\n", + " 'D3': 21,\n", + " 'D4': 22,\n", + " 'D5': 23,\n", + " 'D6': 24,\n", + " 'R1': 25,\n", + " 'R2': 26,\n", + " 'R3': 27,\n", + " 'R4': 28,\n", + " 'R5': 29,\n", + " 'R6': 30,\n", + " 'R7': 31,\n", + " 'R8': 32}" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dict(\n", + " zip(\n", + " [\"{}{}\".format(*a) for a in product([\"A\", \"B\", \"C\", \"D\"], range(1, 7))] + [f\"R{i}\" for i in range(1, 9)], \n", + " range(1, 33)\n", + " )\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[6, 6, 6, 6, 0, 0, 0, 0, 1, 0, 0, 1]\n", + "['A', 'B', 'C', 'D', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8']\n" + ] + } + ], + "source": [ + "relay_layout = [int(i) for i in s46.ask(\":CONF:CPOL?\").split(\",\")]\n", + "relay_names = ([\"A\", \"B\", \"C\", \"D\"] + [f\"R{i}\" for i in range(1, 9)])\n", + "print(relay_layout)\n", + "print(relay_names)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "class RelayLock: \n", + " def __init__(self, relay_name): \n", + " self._relay_name = relay_name\n", + " \n", + " def acquire(self, channel_number): \n", + " pass \n", + " \n", + " def release(self, channel_number):\n", + " pass " + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "class s46Channel: \n", + " def __init__(self, name, channel_number, lock): \n", + " self._name = name \n", + " self._lock = lock\n", + " self._channel_number = channel_number" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [], + "source": [ + "for relay_name, channel_count in zip(relay_names, relay_layout): \n", + " \n", + " relay_lock = RelayLock(relay_name)\n", + " \n", + " for channel_index in range(1, channel_count + 1):\n", + " \n", + " if channel_count > 1:\n", + " alias = f\"{relay_name}{channel_index}\"\n", + " else:\n", + " alias = relay_name\n", + " \n", + " channel_number = aliases[alias]\n", + " channel = s46Channel(alias, channel_number, relay_lock)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "class classproperty:\n", + " def __init__(self, f):\n", + " self.f = f\n", + " def __get__(self, obj, owner):\n", + " return self.f(owner)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "class A: \n", + " @classmethod\n", + " @property\n", + " def aclassprop(cls): \n", + " return 1" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A.aclassprop" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index e61ac3fd8ba..51488e3a4d9 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -1,4 +1,4 @@ -import numpy as np +import itertools import re from typing import cast @@ -11,14 +11,14 @@ class LockAcquisitionError(Exception): class S46Channel(InstrumentChannel): - def __init__(self, parent, name, channel_number, relay): + def __init__(self, parent, name, channel_number, relay_lock): super().__init__(parent, name) self._channel_number = channel_number - self._relay = relay + self._relay_lock = relay_lock if self._get_state() == "close": try: - self._relay.acquire_lock(self._channel_number) + self._relay_lock.acquire(self._channel_number) except LockAcquisitionError as e: raise RuntimeError( "The driver is initialized from an undesirable instrument " @@ -43,9 +43,9 @@ def _get_state(self): def _set_state(self, new_state: str): if new_state == "close": - self._relay.acquire_lock(self._channel_number) + self._relay_lock.acquire(self._channel_number) elif new_state == "open": - self._relay.release_lock(self._channel_number) + self._relay_lock.release(self._channel_number) self.write(f":{new_state} (@{self._channel_number})") @@ -54,66 +54,45 @@ def channel_number(self): return self._channel_number -class S46Relay(InstrumentChannel): - def __init__(self, parent, name, channel_offset, channel_count): - super().__init__(parent, name) - - self._channel_offset = channel_offset +class RelayLock: + def __init__(self, relay_name): + self.relay_name = relay_name self._locked_by = None - channels = ChannelList( - cast(VisaInstrument, self), - "channel", - S46Channel, - snapshotable=False - ) - - for count, channel_number in enumerate(range( - channel_offset, channel_offset + channel_count)): - - if channel_count == 1: - channel_name = self.short_name - else: - channel_name = f"{self.short_name}{count + 1}" - - channel = S46Channel( - cast(VisaInstrument, self.parent), - channel_name, - channel_number, - self - ) - channels.append(channel) - - self.add_submodule("channels", channels) - - def acquire_lock(self, channel_number): + def acquire(self, channel_number): if self._locked_by is not None and self._locked_by != channel_number: raise LockAcquisitionError( - f"Relay {self.short_name} is already in use by channel " + f"Relay {self.relay_name} is already in use by channel " f"{self._locked_by}" ) else: self._locked_by = channel_number - def release_lock(self, channel_number): + def release(self, channel_number): if self._locked_by == channel_number: self._locked_by = None class S46(VisaInstrument): + + channel_aliases = dict( + zip([ + "{}{}".format(*a) + for a in itertools.product(["A", "B", "C", "D"], range(1, 7)) + ] + + [ + f"R{i}" for i in range(1, 9) + ], + range(1, 33)) + ) + + relay_names = ["A", "B", "C", "D"] + [f"R{j}" for j in range(1, 9)] + def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) - relay_layout = [ - int(i) for i in self.ask(":CONF:CPOL?").split(",") - ] - relay_names = (["A", "B", "C", "D"] + [f"R{i}" for i in range(1, 9)]) - # Channel offsets are independent of pole configuration. See page - # 2-5 of the manual - channel_offsets = np.cumsum([0] + 4 * [6] + 7 * [1]) + 1 - channels = ChannelList( self, "channel", @@ -121,11 +100,19 @@ def __init__(self, name, address, **kwargs): snapshotable=False ) - for name, channel_offset, channel_count in zip( - relay_names, channel_offsets, relay_layout): + for relay_name, channel_count in zip(S46.relay_names, self.relay_layout): - relay = S46Relay(self, name, channel_offset, channel_count) - for channel in relay.channels: + relay_lock = RelayLock(relay_name) + + for channel_index in range(1, channel_count + 1): + + if channel_count > 1: + alias = f"{relay_name}{channel_index}" + else: + alias = relay_name + + channel_number = S46.channel_aliases[alias] + channel = S46Channel(self, alias, channel_number, relay_lock) channels.append(channel) self.add_submodule(channel.short_name, channel) @@ -145,3 +132,8 @@ def get_closed_channels(self): def open_all_channels(self): for channel in self.get_closed_channels(): cast(S46Channel, channel).state("open") + + @property + def relay_layout(self): + return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] + diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 2f2a7e43a0e..4e7ebe8abcf 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -1,4 +1,5 @@ import pytest +from itertools import product from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( S46, LockAcquisitionError @@ -40,7 +41,7 @@ def test_open_close(s46): with pytest.raises( LockAcquisitionError, - match="Relay already in use by channel" + match="is already in use by channel" ): s46.channels[1].state("close") @@ -50,6 +51,23 @@ def test_open_close(s46): with pytest.raises( LockAcquisitionError, - match="Relay already in use by channel" + match="is already in use by channel" ): s46.channels[19].state("close") + + +def test_aliases(s46): + + hex_aliases = [ + f"{a}{b}" for a, b in product( + ["A", "B", "C", "D"], + list(range(1, 7)) + ) + ] + + aliases = hex_aliases + [f"R{i}" for i in range(1, 9)] + + for channel in s46.channels: + idx = channel.channel_number - 1 + alias = aliases[idx] + assert getattr(s46, alias) is channel From 3fb4007f24a10bfea4d4c7c12ec29ad3e432e48d Mon Sep 17 00:00:00 2001 From: Neil Dick Date: Mon, 3 Dec 2018 14:05:38 +1100 Subject: [PATCH 309/719] feat: Add model number 33511B The 33511B is a single channel model with a maximum frequency of 20 MHz. --- qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py index eb00573be4f..f85897ff794 100644 --- a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py +++ b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py @@ -290,11 +290,13 @@ def __init__(self, name, address, silent=False, **kwargs): # TODO: Fill out this dict with all models no_of_channels = {'33210A': 1, '33250A': 1, + '33511B': 1, '33522B': 2, '33622A': 2 } self._max_freqs = {'33210A': 10e6, + '33511B': 20e6, '33250A': 80e6, '33522B': 30e6, '33622A': 120e6} From d99f93d89f34062ff3a0f312ced2240c03a7d3ab Mon Sep 17 00:00:00 2001 From: Neil Dick Date: Mon, 3 Dec 2018 14:09:30 +1100 Subject: [PATCH 310/719] feat: Add parameter to set pulse width Add a channel parameter to set the width of the pulse function --- .../instrument_drivers/Keysight/KeysightAgilent_33XXX.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py index f85897ff794..3ef0e300626 100644 --- a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py +++ b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py @@ -128,6 +128,13 @@ def val_parser(parser: type, inputstring: str) -> Union[float,int]: vals=vals.Numbers(0, 100) ) + self.add_parameter('pulse_width', + label="Channel {} pulse width".format(channum), + set_cmd='SOURce{}:FUNCtion:PULSE:WIDTh {{}}'.format(channum), + get_cmd='SOURce{}:FUNCtion:PULSE:WIDTh?'.format(channum), + get_parser=float, + unit='S') + # TRIGGER MENU self.add_parameter('trigger_source', label='Channel {} trigger source'.format(channum), From 200561c5fc1facfb8dfcd2ea44b72ad7a1cb20b7 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 15:40:30 +1100 Subject: [PATCH 311/719] Close websockets connection on disconnect --- qcodes/monitor/monitor.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index c12f255533a..56fbc8a43b8 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -11,6 +11,7 @@ """ import asyncio +from asyncio import CancelledError import logging import os import time @@ -21,12 +22,8 @@ import datetime from copy import deepcopy from contextlib import suppress - from threading import Thread from typing import Dict, Any -from asyncio import CancelledError -import functools - import websockets SERVER_PORT = 3000 @@ -85,6 +82,7 @@ async def serverFunc(websocket, path): # mute browser disconnects except websockets.exceptions.ConnectionClosed as e: log.debug(e) + break await asyncio.sleep(interval) except CancelledError: log.debug("Got CancelledError") @@ -171,6 +169,11 @@ def join(self, timeout=None) -> None: joining avoiding a potential deadlock. """ log.debug("Shutting down server") + if not self.isAlive(): + # we run this check before trying to run to prevent a cryptic + # error message + log.debug("monitor is dead") + return try: asyncio.run_coroutine_threadsafe(self.__stop_server(), self.loop) except RuntimeError as e: @@ -183,6 +186,8 @@ def join(self, timeout=None) -> None: log.debug("Loop reported closed") super().join(timeout=timeout) log.debug("Monitor Thread has joined") + if Monitor.running == self: + Monitor.running = None @staticmethod def show(): From dec4d74487345b8c3abf659f75610bb5bdb86fa0 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 16:41:41 +1100 Subject: [PATCH 312/719] Improve documentation of _handler --- qcodes/monitor/monitor.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 56fbc8a43b8..48fe682abb0 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -67,8 +67,10 @@ def _get_metadata(*parameters) -> Dict[str, Any]: def _handler(parameters, interval: int): - - async def serverFunc(websocket, path): + """ + Return the websockets server handler + """ + async def server_func(websocket, path): while True: try: try: @@ -88,9 +90,9 @@ async def serverFunc(websocket, path): log.debug("Got CancelledError") break - log.debug("Stopping Websocket handler") + log.debug("Closing websockets connection") - return serverFunc + return server_func class Monitor(Thread): From 426bb4a564687fbfc64878854a39f986243f5289 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 16:42:22 +1100 Subject: [PATCH 313/719] Don't use private parameters to find instrument root --- qcodes/monitor/monitor.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 48fe682abb0..e090cda463c 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -52,9 +52,7 @@ def _get_metadata(*parameters) -> Dict[str, Any]: meta["name"] = parameter.label or parameter.name meta["unit"] = parameter.unit # find the base instrument in case this is a channel parameter - baseinst = parameter._instrument - while hasattr(baseinst, '_parent'): - baseinst = baseinst._parent + baseinst = parameter.root_instrument accumulator = metas.get(str(baseinst), []) accumulator.append(meta) metas[str(baseinst)] = accumulator From fee75c49a70d12cee6f3559a1aac5968ee41c0b1 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 16:43:27 +1100 Subject: [PATCH 314/719] Use Event to flag server shutdown instead of global flag --- qcodes/monitor/monitor.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index e090cda463c..4d2833392cc 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -22,7 +22,7 @@ import datetime from copy import deepcopy from contextlib import suppress -from threading import Thread +from threading import Thread, Event from typing import Dict, Any import websockets @@ -110,7 +110,7 @@ def __init__(self, *parameters, interval=1): super().__init__() self.loop = None self._parameters = parameters - self._monitor(*parameters, interval=interval) + self.loop_is_closed = Event() Monitor.running = self def run(self): @@ -137,8 +137,8 @@ def run(self): while not self.loop.is_closed(): log.debug("waiting for loop to stop and close") time.sleep(0.01) - self.loop_is_closed = True log.debug("loop closed") + self.loop_is_closed.set() def update_all(self): for p in self._parameters: @@ -180,9 +180,7 @@ def join(self, timeout=None) -> None: # the above may throw a runtime error if the loop is already # stopped in which case there is nothing more to do log.exception("Could not close loop") - while not self.loop_is_closed: - log.debug("waiting for loop to stop and close") - time.sleep(0.01) + self.loop_is_closed.wait() log.debug("Loop reported closed") super().join(timeout=timeout) log.debug("Monitor Thread has joined") From ed7b18dad334490dd2be2cee1a69caf8475aecb1 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 16:43:50 +1100 Subject: [PATCH 315/719] Refactor monitor initializer, remove unessecary function --- qcodes/monitor/monitor.py | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 4d2833392cc..878b8990502 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -111,6 +111,16 @@ def __init__(self, *parameters, interval=1): self.loop = None self._parameters = parameters self.loop_is_closed = Event() + # TODO (giulioungaretti) read from config + self.handler = _handler(parameters, interval=interval) + + log.debug("Start monitoring thread") + if Monitor.running: + # stop the old server + log.debug("Stopping and restarting server") + Monitor.running.stop() + self.start() + Monitor.running = self def run(self): @@ -119,7 +129,6 @@ def run(self): """ log.debug("Running Websocket server") self.loop = asyncio.new_event_loop() - self.loop_is_closed = False asyncio.set_event_loop(self.loop) try: server_start = websockets.serve(self.handler, '127.0.0.1', 5678) @@ -203,24 +212,6 @@ def show(): """ webbrowser.open("http://localhost:{}".format(SERVER_PORT)) - def _monitor(self, *parameters, interval=1): - self.handler = _handler(parameters, interval=interval) - # TODO (giulioungaretti) read from config - - log.debug("Start monitoring thread") - - if Monitor.running: - # stop the old server - log.debug("Stopping and restarting server") - Monitor.running.stop() - - self.start() - - # let the thread start - time.sleep(0.01) - log.debug("Start monitoring server") - - class Server(): def __init__(self, port=3000): From 6fe807efcbe74e34f21ac5d139b6004a3aeaddbe Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 17:27:16 +1100 Subject: [PATCH 316/719] Use correct is_alive for threads --- qcodes/monitor/monitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 878b8990502..aa3386c1c28 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -178,7 +178,7 @@ def join(self, timeout=None) -> None: joining avoiding a potential deadlock. """ log.debug("Shutting down server") - if not self.isAlive(): + if not self.is_alive(): # we run this check before trying to run to prevent a cryptic # error message log.debug("monitor is dead") From ecd8b3b3a7c7495dd2997df3d7d9124615ade77f Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 20:24:02 +1100 Subject: [PATCH 317/719] Refactor, remove references to private functions. - _handler now uses get_latest to access parameter values, causing update after max_age. - added get_timestamp to get_latest which returns age of data - various readability improvements --- qcodes/instrument/parameter.py | 7 ++++ qcodes/monitor/monitor.py | 74 ++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 1de617b086f..f70466d83b4 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -1364,6 +1364,13 @@ def get(self): else: return state['value'] + def get_timestamp(self): + """ + Return the age of the last get_latest call. + """ + state = self.parameter._latest + return state["ts"] + def __call__(self): return self.get() diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index aa3386c1c28..8d9d213f2dd 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -10,21 +10,25 @@ stream opuput over websocket """ -import asyncio -from asyncio import CancelledError import logging import os import time import json -import http.server -import socketserver -import webbrowser import datetime -from copy import deepcopy from contextlib import suppress -from threading import Thread, Event from typing import Dict, Any +from collections import defaultdict + +import asyncio +from asyncio import CancelledError +from threading import Thread, Event + +import http.server +import socketserver import websockets +import webbrowser + +from qcodes.base.parameter import _BaseParameter SERVER_PORT = 3000 @@ -37,29 +41,33 @@ def _get_metadata(*parameters) -> Dict[str, Any]: instrument it belongs to. """ ts = time.time() - # group meta data by instrument if any - metas = {} # type: Dict + # group metadata by instrument + metas = defaultdict(list) # type: dict for parameter in parameters: - _meta = getattr(parameter, "_latest", None) - if _meta: - meta = deepcopy(_meta) - else: - raise ValueError("Input is not a parameter; Refusing to proceed") - # convert to string - meta['value'] = str(meta['value']) - if isinstance(meta["ts"], datetime.datetime): - meta["ts"] = time.mktime(meta["ts"].timetuple()) + # Check we have a list of parameters + if not isinstance(parameter, _BaseParameter): + raise ValueError("{} is not a parameter".format(parameter)) + + # Get the latest value from the parameter, respecting the max_val_age parameter + meta = {} + meta["value"] = str(parameter.get_latest()) + meta["ts"] = str(time.mktime(parameter.get_latest.get_timestamp.timestamp())) meta["name"] = parameter.label or parameter.name meta["unit"] = parameter.unit - # find the base instrument in case this is a channel parameter + + # find the base instrument that this parameter belongs to baseinst = parameter.root_instrument - accumulator = metas.get(str(baseinst), []) - accumulator.append(meta) - metas[str(baseinst)] = accumulator + if baseinst is None: + metas["No Instrument"].append(meta) + else: + metas[str(baseinst)].append(meta) + + # Create list of parameters, grouped by instrument parameters_out = [] for instrument in metas: temp = {"instrument": instrument, "parameters": metas[instrument]} parameters_out.append(temp) + state = {"ts": ts, "parameters": parameters_out} return state @@ -69,30 +77,29 @@ def _handler(parameters, interval: int): Return the websockets server handler """ async def server_func(websocket, path): + """ + Create a websockets handler that sends parameter values to a listener + every "interval" seconds + """ while True: try: + # Update the parameter values try: meta = _get_metadata(*parameters) except ValueError as e: log.exception(e) break log.debug(f"sending.. to {websocket}") - try: - await websocket.send(json.dumps(meta)) - # mute browser disconnects - except websockets.exceptions.ConnectionClosed as e: - log.debug(e) - break + await websocket.send(json.dumps(meta)) + # Wait for interval seconds and then send again await asyncio.sleep(interval) - except CancelledError: - log.debug("Got CancelledError") + except (CancelledError, websockets.exceptions.ConnectionClosed): + log.debug("Got CancelledError or ConnectionClosed") break - log.debug("Closing websockets connection") return server_func - class Monitor(Thread): running = None server = None @@ -105,13 +112,10 @@ def __init__(self, *parameters, interval=1): *parameters: Parameters to monitor interval: How often one wants to refresh the values """ - # let the thread start - time.sleep(0.01) super().__init__() self.loop = None self._parameters = parameters self.loop_is_closed = Event() - # TODO (giulioungaretti) read from config self.handler = _handler(parameters, interval=interval) log.debug("Start monitoring thread") From 4d5cfb8c8cdb4da506d76d17feb6a98e38b660a9 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 20:51:44 +1100 Subject: [PATCH 318/719] Reorder/fix monitor imports --- qcodes/monitor/monitor.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 8d9d213f2dd..0280c74d2fc 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -14,7 +14,6 @@ import os import time import json -import datetime from contextlib import suppress from typing import Dict, Any from collections import defaultdict @@ -25,10 +24,10 @@ import http.server import socketserver -import websockets import webbrowser +import websockets -from qcodes.base.parameter import _BaseParameter +from qcodes.instrument.parameter import _BaseParameter SERVER_PORT = 3000 From ac7788d0ce62c6b9dad07e9813825a9efa466f38 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 20:52:22 +1100 Subject: [PATCH 319/719] Make server port configurable in file --- qcodes/monitor/monitor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 0280c74d2fc..d26abebb4e3 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -29,6 +29,7 @@ from qcodes.instrument.parameter import _BaseParameter +WEBSOCKET_PORT = 5678 SERVER_PORT = 3000 log = logging.getLogger(__name__) @@ -134,7 +135,7 @@ def run(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) try: - server_start = websockets.serve(self.handler, '127.0.0.1', 5678) + server_start = websockets.serve(self.handler, '127.0.0.1', WEBSOCKET_PORT) self.server = self.loop.run_until_complete(server_start) self.loop.run_forever() except OSError as e: @@ -217,7 +218,7 @@ def show(): class Server(): - def __init__(self, port=3000): + def __init__(self, port=SERVER_PORT): self.port = port self.handler = http.server.SimpleHTTPRequestHandler self.httpd = socketserver.TCPServer(("", self.port), self.handler) @@ -226,7 +227,6 @@ def __init__(self, port=3000): def run(self): os.chdir(self.static_dir) log.debug("serving directory %s", self.static_dir) - log.info("Open browser at http://localhost::{}".format(self.port)) self.httpd.serve_forever() def stop(self): @@ -234,7 +234,7 @@ def stop(self): if __name__ == "__main__": - server = Server(SERVER_PORT) + server = Server() print("Open browser at http://localhost:{}".format(server.port)) try: webbrowser.open("http://localhost:{}".format(server.port)) From a7dce6adadfa60a9fdb7f47914ab2bdac27066e7 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 20:52:47 +1100 Subject: [PATCH 320/719] Improve documentation --- qcodes/monitor/monitor.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index d26abebb4e3..ef1a204073c 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -89,7 +89,7 @@ async def server_func(websocket, path): except ValueError as e: log.exception(e) break - log.debug(f"sending.. to {websocket}") + log.debug("sending.. to %r", websocket) await websocket.send(json.dumps(meta)) # Wait for interval seconds and then send again await asyncio.sleep(interval) @@ -101,8 +101,10 @@ async def server_func(websocket, path): return server_func class Monitor(Thread): + """ + QCodes Monitor - WebSockets server to monitor qcodes parameters + """ running = None - server = None def __init__(self, *parameters, interval=1): """ @@ -114,6 +116,7 @@ def __init__(self, *parameters, interval=1): """ super().__init__() self.loop = None + self.server = None self._parameters = parameters self.loop_is_closed = Event() self.handler = _handler(parameters, interval=interval) @@ -138,22 +141,22 @@ def run(self): server_start = websockets.serve(self.handler, '127.0.0.1', WEBSOCKET_PORT) self.server = self.loop.run_until_complete(server_start) self.loop.run_forever() - except OSError as e: + except OSError: # The code above may throw an OSError # if the socket cannot be bound - log.exception(e) + log.exception("Server could not be started") finally: log.debug("loop stopped") - log.debug("Pending tasks at close: {}".format( - asyncio.Task.all_tasks(self.loop))) + log.debug("Pending tasks at close: %r", + asyncio.Task.all_tasks(self.loop)) self.loop.close() - while not self.loop.is_closed(): - log.debug("waiting for loop to stop and close") - time.sleep(0.01) log.debug("loop closed") self.loop_is_closed.set() def update_all(self): + """ + Update all parameters in the monitor + """ for p in self._parameters: # call get if it can be called without arguments with suppress(TypeError): @@ -173,7 +176,8 @@ async def __stop_server(self): log.debug("waiting for server to close") await self.loop.create_task(self.server.wait_closed()) log.debug("stopping loop") - log.debug("Pending tasks at stop: {}".format(asyncio.Task.all_tasks(self.loop))) + log.debug("Pending tasks at stop: %r", + asyncio.Task.all_tasks(self.loop)) self.loop.stop() def join(self, timeout=None) -> None: @@ -189,7 +193,7 @@ def join(self, timeout=None) -> None: return try: asyncio.run_coroutine_threadsafe(self.__stop_server(), self.loop) - except RuntimeError as e: + except RuntimeError: # the above may throw a runtime error if the loop is already # stopped in which case there is nothing more to do log.exception("Could not close loop") @@ -197,8 +201,6 @@ def join(self, timeout=None) -> None: log.debug("Loop reported closed") super().join(timeout=timeout) log.debug("Monitor Thread has joined") - if Monitor.running == self: - Monitor.running = None @staticmethod def show(): From 56c387a7781748b37b8da412ac2f0d47e4312821 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 21:08:54 +1100 Subject: [PATCH 321/719] Monitor can only really look at parameters. This is since labels and units are only really defined for those, and they are necessary for display --- qcodes/monitor/monitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index ef1a204073c..c76c9fa7c59 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -27,7 +27,7 @@ import webbrowser import websockets -from qcodes.instrument.parameter import _BaseParameter +from qcodes.instrument.parameter import Parameter WEBSOCKET_PORT = 5678 SERVER_PORT = 3000 @@ -45,13 +45,13 @@ def _get_metadata(*parameters) -> Dict[str, Any]: metas = defaultdict(list) # type: dict for parameter in parameters: # Check we have a list of parameters - if not isinstance(parameter, _BaseParameter): + if not isinstance(parameter, Parameter): raise ValueError("{} is not a parameter".format(parameter)) # Get the latest value from the parameter, respecting the max_val_age parameter meta = {} meta["value"] = str(parameter.get_latest()) - meta["ts"] = str(time.mktime(parameter.get_latest.get_timestamp.timestamp())) + meta["ts"] = str(time.mktime(parameter.get_latest.get_timestamp().timestamp())) meta["name"] = parameter.label or parameter.name meta["unit"] = parameter.unit From 0163ec09d2892ce4825e708df30f28f91815ef00 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 21:54:09 +1100 Subject: [PATCH 322/719] Handle unset parameters in monitor --- qcodes/monitor/monitor.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index c76c9fa7c59..d7a485f5a9c 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -51,14 +51,17 @@ def _get_metadata(*parameters) -> Dict[str, Any]: # Get the latest value from the parameter, respecting the max_val_age parameter meta = {} meta["value"] = str(parameter.get_latest()) - meta["ts"] = str(time.mktime(parameter.get_latest.get_timestamp().timestamp())) + if parameter.get_latest.get_timestamp() is not None: + meta["ts"] = str(parameter.get_latest.get_timestamp().timestamp()) + else: + meta["ts"] = None meta["name"] = parameter.label or parameter.name meta["unit"] = parameter.unit # find the base instrument that this parameter belongs to baseinst = parameter.root_instrument if baseinst is None: - metas["No Instrument"].append(meta) + metas["Unbound Parameter"].append(meta) else: metas[str(baseinst)].append(meta) From a21a5528bb2e4d81fddf8b3fd400d1dcb134c94b Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 21:54:16 +1100 Subject: [PATCH 323/719] Add monitor tests --- qcodes/tests/test_monitor.py | 125 +++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 qcodes/tests/test_monitor.py diff --git a/qcodes/tests/test_monitor.py b/qcodes/tests/test_monitor.py new file mode 100644 index 00000000000..e133da6bceb --- /dev/null +++ b/qcodes/tests/test_monitor.py @@ -0,0 +1,125 @@ +""" +Test suite for monitor +""" +from unittest import TestCase + +import time +import asyncio +import websockets +import json +import random + +import qcodes as qc +from qcodes.instrument.base import Parameter +from qcodes.tests.instrument_mocks import DummyInstrument + +class TestMonitor(TestCase): + """ + Test cases for the qcodes monitor + """ + def test_setup_teardown(self): + """ + Check that monitor starts up and closes correctly + """ + m = qc.Monitor() + self.assertTrue(m.is_alive()) + # Wait for loop to start + while m.loop is None: + time.sleep(0.01) + self.assertTrue(m.loop.is_running()) + self.assertEqual(qc.Monitor.running, m) + m.stop() + self.assertFalse(m.loop.is_running()) + self.assertTrue(m.loop.is_closed()) + self.assertFalse(m.is_alive()) + self.assertIsNone(qc.Monitor.running) + + def test_connection(self): + """ + Test that we can connect to a monitor instance + """ + m = qc.Monitor() + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + @asyncio.coroutine + def async_test_connection(): + websocket = yield from websockets.connect(f"ws://localhost:{qc.monitor.monitor.WEBSOCKET_PORT}") + yield from websocket.close() + loop.run_until_complete(async_test_connection()) + + m.stop() + +class TestMonitorWithInstr(TestCase): + """ + Test monitor values from instruments + """ + def setUp(self): + """ + Create a dummy instrument for use in monitor tests, and hook it into + a monitor + """ + self.instr = DummyInstrument("MonitorDummy") + self.param = Parameter("DummyParam", + unit="V", + get_cmd=None, + set_cmd=None) + self.param(1) + self.monitor_parameters = tuple(self.instr.parameters.values())[1:] + self.monitor = qc.Monitor(*self.monitor_parameters, self.param) + + def tearDown(self): + """ + Close the dummy instrument + """ + self.monitor.stop() + self.instr.close() + + def test_parameter(self): + """ + Test instrument updates + """ + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + @asyncio.coroutine + def async_test_monitor(): + websocket = yield from websockets.connect(f"ws://localhost:{qc.monitor.monitor.WEBSOCKET_PORT}") + + # Recieve data from monitor + data = yield from websocket.recv() + data = json.loads(data) + # Check fields + self.assertIn("ts", data) + self.assertIn("parameters", data) + # Check one instrument and "No Instrument" is being sent + self.assertEqual(len(data["parameters"]), 2) + self.assertEqual(data["parameters"][1]["instrument"], "Unbound Parameter") + metadata = data["parameters"][0] + self.assertEqual(metadata["instrument"], str(self.instr)) + + # Check parameter values + old_timestamps = {} + for local, monitor in zip(self.monitor_parameters, metadata["parameters"]): + self.assertEqual(str(local.get_latest()), monitor["value"]) + self.assertEqual(local.label, monitor["name"]) + old_timestamps[local.label] = float(monitor["ts"]) + local(random.random()) + + # Check parameter updates + data = yield from websocket.recv() + data = yield from websocket.recv() + data = json.loads(data) + metadata = data["parameters"][0] + for local, monitor in zip(self.monitor_parameters, metadata["parameters"]): + self.assertEqual(str(local.get_latest()), monitor["value"]) + self.assertEqual(local.label, monitor["name"]) + self.assertGreater(float(monitor["ts"]), old_timestamps[local.label]) + + # Check unbound parameter + metadata = data["parameters"][1]["parameters"] + self.assertEqual(len(metadata), 1) + self.assertEqual(self.param.label, metadata[0]["name"]) + + loop.run_until_complete(async_test_monitor()) From eee6fe01c99f312dda33b771c99ca1a87bdc417c Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 22:13:32 +1100 Subject: [PATCH 324/719] Correct datatype for timestamp --- qcodes/monitor/monitor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index d7a485f5a9c..8ce7309f070 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -52,7 +52,7 @@ def _get_metadata(*parameters) -> Dict[str, Any]: meta = {} meta["value"] = str(parameter.get_latest()) if parameter.get_latest.get_timestamp() is not None: - meta["ts"] = str(parameter.get_latest.get_timestamp().timestamp()) + meta["ts"] = parameter.get_latest.get_timestamp().timestamp() else: meta["ts"] = None meta["name"] = parameter.label or parameter.name @@ -131,6 +131,9 @@ def __init__(self, *parameters, interval=1): Monitor.running.stop() self.start() + # Wait until the loop is running + while self.loop is None: + time.sleep(0.01) Monitor.running = self def run(self): From 97ca268bef9958aef3dd64121ec6d700145e9086 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 22:32:20 +1100 Subject: [PATCH 325/719] Use randomized port for monitor tests --- qcodes/tests/test_monitor.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/qcodes/tests/test_monitor.py b/qcodes/tests/test_monitor.py index e133da6bceb..c7aa987db69 100644 --- a/qcodes/tests/test_monitor.py +++ b/qcodes/tests/test_monitor.py @@ -5,14 +5,16 @@ import time import asyncio -import websockets import json import random +import websockets -import qcodes as qc +from qcodes.monitor import monitor from qcodes.instrument.base import Parameter from qcodes.tests.instrument_mocks import DummyInstrument +monitor.WEBSOCKET_PORT = random.randint(50000, 60000) + class TestMonitor(TestCase): """ Test cases for the qcodes monitor @@ -21,31 +23,31 @@ def test_setup_teardown(self): """ Check that monitor starts up and closes correctly """ - m = qc.Monitor() + m = monitor.Monitor() self.assertTrue(m.is_alive()) # Wait for loop to start while m.loop is None: time.sleep(0.01) self.assertTrue(m.loop.is_running()) - self.assertEqual(qc.Monitor.running, m) + self.assertEqual(monitor.Monitor.running, m) m.stop() self.assertFalse(m.loop.is_running()) self.assertTrue(m.loop.is_closed()) self.assertFalse(m.is_alive()) - self.assertIsNone(qc.Monitor.running) + self.assertIsNone(monitor.Monitor.running) def test_connection(self): """ Test that we can connect to a monitor instance """ - m = qc.Monitor() + m = monitor.Monitor() loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) @asyncio.coroutine def async_test_connection(): - websocket = yield from websockets.connect(f"ws://localhost:{qc.monitor.monitor.WEBSOCKET_PORT}") + websocket = yield from websockets.connect(f"ws://localhost:{monitor.WEBSOCKET_PORT}") yield from websocket.close() loop.run_until_complete(async_test_connection()) @@ -67,7 +69,7 @@ def setUp(self): set_cmd=None) self.param(1) self.monitor_parameters = tuple(self.instr.parameters.values())[1:] - self.monitor = qc.Monitor(*self.monitor_parameters, self.param) + self.monitor = monitor.Monitor(*self.monitor_parameters, self.param, interval=0.1) def tearDown(self): """ @@ -85,7 +87,7 @@ def test_parameter(self): @asyncio.coroutine def async_test_monitor(): - websocket = yield from websockets.connect(f"ws://localhost:{qc.monitor.monitor.WEBSOCKET_PORT}") + websocket = yield from websockets.connect(f"ws://localhost:{monitor.WEBSOCKET_PORT}") # Recieve data from monitor data = yield from websocket.recv() @@ -101,10 +103,10 @@ def async_test_monitor(): # Check parameter values old_timestamps = {} - for local, monitor in zip(self.monitor_parameters, metadata["parameters"]): - self.assertEqual(str(local.get_latest()), monitor["value"]) - self.assertEqual(local.label, monitor["name"]) - old_timestamps[local.label] = float(monitor["ts"]) + for local, mon in zip(self.monitor_parameters, metadata["parameters"]): + self.assertEqual(str(local.get_latest()), mon["value"]) + self.assertEqual(local.label, mon["name"]) + old_timestamps[local.label] = float(mon["ts"]) local(random.random()) # Check parameter updates @@ -112,10 +114,10 @@ def async_test_monitor(): data = yield from websocket.recv() data = json.loads(data) metadata = data["parameters"][0] - for local, monitor in zip(self.monitor_parameters, metadata["parameters"]): - self.assertEqual(str(local.get_latest()), monitor["value"]) - self.assertEqual(local.label, monitor["name"]) - self.assertGreater(float(monitor["ts"]), old_timestamps[local.label]) + for local, mon in zip(self.monitor_parameters, metadata["parameters"]): + self.assertEqual(str(local.get_latest()), mon["value"]) + self.assertEqual(local.label, mon["name"]) + self.assertGreater(float(mon["ts"]), old_timestamps[local.label]) # Check unbound parameter metadata = data["parameters"][1]["parameters"] From 85858ff8ba06d5ba7628fccd41fd8be6f307b017 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Mon, 3 Dec 2018 23:53:45 +1100 Subject: [PATCH 326/719] Wait for loop to start before returning monitor --- qcodes/monitor/monitor.py | 2 +- qcodes/tests/test_monitor.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 8ce7309f070..1f0fae77ecd 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -132,7 +132,7 @@ def __init__(self, *parameters, interval=1): self.start() # Wait until the loop is running - while self.loop is None: + while self.loop is None or not self.loop.is_running(): time.sleep(0.01) Monitor.running = self diff --git a/qcodes/tests/test_monitor.py b/qcodes/tests/test_monitor.py index c7aa987db69..c17943e6cbe 100644 --- a/qcodes/tests/test_monitor.py +++ b/qcodes/tests/test_monitor.py @@ -25,9 +25,6 @@ def test_setup_teardown(self): """ m = monitor.Monitor() self.assertTrue(m.is_alive()) - # Wait for loop to start - while m.loop is None: - time.sleep(0.01) self.assertTrue(m.loop.is_running()) self.assertEqual(monitor.Monitor.running, m) m.stop() From 7483cc658c2dfb3c7e1eeb792c4978aac3fd32e0 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Tue, 4 Dec 2018 00:00:16 +1100 Subject: [PATCH 327/719] Use event to wait for server start --- qcodes/monitor/monitor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 1f0fae77ecd..b090709784a 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -122,6 +122,7 @@ def __init__(self, *parameters, interval=1): self.server = None self._parameters = parameters self.loop_is_closed = Event() + self.server_is_started = Event() self.handler = _handler(parameters, interval=interval) log.debug("Start monitoring thread") @@ -132,8 +133,7 @@ def __init__(self, *parameters, interval=1): self.start() # Wait until the loop is running - while self.loop is None or not self.loop.is_running(): - time.sleep(0.01) + self.server_is_started.wait() Monitor.running = self def run(self): @@ -146,6 +146,7 @@ def run(self): try: server_start = websockets.serve(self.handler, '127.0.0.1', WEBSOCKET_PORT) self.server = self.loop.run_until_complete(server_start) + self.server_is_started.set() self.loop.run_forever() except OSError: # The code above may throw an OSError From 561578248b2ad99beabec29e5762426beea55f6a Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 11:13:06 -0800 Subject: [PATCH 328/719] test work now --- .../QCodes example with Keithley S46.ipynb | 228 +++++++----------- qcodes/instrument/sims/Keithley_s46.yaml | 33 ++- .../tektronix/Keithley_s46.py | 51 ++-- qcodes/tests/drivers/test_keithley_s46.py | 73 ++++-- 4 files changed, 193 insertions(+), 192 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 6405988ca0a..6685d57991b 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 20, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,14 +11,14 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.20s\n" + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.62s\n" ] } ], @@ -34,9 +34,7 @@ { "data": { "text/plain": [ - "[,\n", - " ,\n", - " ]" + "[]" ] }, "execution_count": 3, @@ -223,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -232,7 +230,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -241,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -250,220 +248,160 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "s46.open_all_channels()" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "s46.A1.state(\"open\")" - ] - }, - { - "cell_type": "code", - "execution_count": 70, + "execution_count": 32, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'A1': 1, 'A2': 2, 'A3': 3, 'A4': 4, 'A5': 5, 'A6': 6, 'B1': 7, 'B2': 8, 'B3': 9, 'B4': 10, 'B5': 11, 'B6': 12, 'C1': 13, 'C2': 14, 'C3': 15, 'C4': 16, 'C5': 17, 'C6': 18, 'D1': 19, 'D2': 20, 'D3': 21, 'D4': 22, 'D5': 23, 'D6': 24, 'R1': 25, 'R2': 26, 'R3': 27, 'R4': 28, 'R5': 29, 'R6': 30, 'R7': 31, 'R8': 32}\n" - ] + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ]" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "channel_aliases = [\n", - " f\"{relay_name}{index}\" for\n", - " relay_name, index in product(\n", - " [\"A\", \"B\", \"C\", \"D\"],\n", - " range(1, 7)\n", - " )\n", - "]\n", - "channel_aliases += [f\"R{i}\" for i in range(1, 9)]\n", - "\n", - "print(dict(zip(channel_aliases, range(1, 33))))" + "s46.get_closed_channels()" ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'A1': 1,\n", - " 'A2': 2,\n", - " 'A3': 3,\n", - " 'A4': 4,\n", - " 'A5': 5,\n", - " 'A6': 6,\n", - " 'B1': 7,\n", - " 'B2': 8,\n", - " 'B3': 9,\n", - " 'B4': 10,\n", - " 'B5': 11,\n", - " 'B6': 12,\n", - " 'C1': 13,\n", - " 'C2': 14,\n", - " 'C3': 15,\n", - " 'C4': 16,\n", - " 'C5': 17,\n", - " 'C6': 18,\n", - " 'D1': 19,\n", - " 'D2': 20,\n", - " 'D3': 21,\n", - " 'D4': 22,\n", - " 'D5': 23,\n", - " 'D6': 24,\n", - " 'R1': 25,\n", - " 'R2': 26,\n", - " 'R3': 27,\n", - " 'R4': 28,\n", - " 'R5': 29,\n", - " 'R6': 30,\n", - " 'R7': 31,\n", - " 'R8': 32}" + "[1, 7, 32]" ] }, - "execution_count": 72, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "dict(\n", - " zip(\n", - " [\"{}{}\".format(*a) for a in product([\"A\", \"B\", \"C\", \"D\"], range(1, 7))] + [f\"R{i}\" for i in range(1, 9)], \n", - " range(1, 33)\n", - " )\n", - ")" + "s46.get_closed_channel_numbers()" ] }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[6, 6, 6, 6, 0, 0, 0, 0, 1, 0, 0, 1]\n", - "['A', 'B', 'C', 'D', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8']\n" + "1\n", + "7\n", + "32\n" ] } ], "source": [ - "relay_layout = [int(i) for i in s46.ask(\":CONF:CPOL?\").split(\",\")]\n", - "relay_names = ([\"A\", \"B\", \"C\", \"D\"] + [f\"R{i}\" for i in range(1, 9)])\n", - "print(relay_layout)\n", - "print(relay_names)" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [], - "source": [ - "class RelayLock: \n", - " def __init__(self, relay_name): \n", - " self._relay_name = relay_name\n", - " \n", - " def acquire(self, channel_number): \n", - " pass \n", - " \n", - " def release(self, channel_number):\n", - " pass " + "print(S46.alias_to_channel_number(\"A1\"))\n", + "print(S46.alias_to_channel_number(\"B1\"))\n", + "print(S46.alias_to_channel_number(\"R8\"))" ] }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ - "class s46Channel: \n", - " def __init__(self, name, channel_number, lock): \n", - " self._name = name \n", - " self._lock = lock\n", - " self._channel_number = channel_number" + "def channel_number_to_alias(num): \n", + " n = num - 24\n", + " if n > 0: \n", + " return f\"R{n}\"\n", + " index = num % 6\n", + " relay = {0: \"A\", 1: \"B\", 2: \"C\", 3: \"D\"}[(num - 1)//6]\n", + " return f\"{relay}{index}\"" ] }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 40, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A1\n", + "B1\n", + "R8\n" + ] + } + ], "source": [ - "for relay_name, channel_count in zip(relay_names, relay_layout): \n", - " \n", - " relay_lock = RelayLock(relay_name)\n", - " \n", - " for channel_index in range(1, channel_count + 1):\n", - " \n", - " if channel_count > 1:\n", - " alias = f\"{relay_name}{channel_index}\"\n", - " else:\n", - " alias = relay_name\n", - " \n", - " channel_number = aliases[alias]\n", - " channel = s46Channel(alias, channel_number, relay_lock)" + "print(channel_number_to_alias(1))\n", + "print(channel_number_to_alias(7))\n", + "print(channel_number_to_alias(32))" ] }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 41, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A2\n", + "B2\n", + "R7\n" + ] + } + ], "source": [ - "class classproperty:\n", - " def __init__(self, f):\n", - " self.f = f\n", - " def __get__(self, obj, owner):\n", - " return self.f(owner)" + "print(channel_number_to_alias(2))\n", + "print(channel_number_to_alias(8))\n", + "print(channel_number_to_alias(31))" ] }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ - "class A: \n", - " @classmethod\n", - " @property\n", - " def aclassprop(cls): \n", - " return 1" + "s46.open_all_channels()" ] }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + "[]" ] }, - "execution_count": 62, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "A.aclassprop" + "s46.get_closed_channels()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "s46.A1.state(\"open\")" ] }, { diff --git a/qcodes/instrument/sims/Keithley_s46.yaml b/qcodes/instrument/sims/Keithley_s46.yaml index 0b9bcca7605..66f9789933d 100644 --- a/qcodes/instrument/sims/Keithley_s46.yaml +++ b/qcodes/instrument/sims/Keithley_s46.yaml @@ -20,7 +20,7 @@ devices: q: ":CLOS?" r: "(@1,2,8)" - device default: + device six: eom: GPIB INSTR: q: "\n" @@ -47,8 +47,37 @@ devices: q: ":OPEN {}" r: "" + device four: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "KEITHLEY INSTRUMENTS INC.,MODEL SYSTEM 46, 1327388, A03 " + - q: ":CONF:CPOL?" + r: "4,4,4,4,0,0,0,0,1,0,0,1" + + properties: + + close: + getter: + q: ":CLOS?" + r: "(@1,8)" + setter: + q: ":CLOS {}" + r: "" + + open: + setter: + q: ":OPEN {}" + r: "" + resources: GPIB::1::INSTR: device: device bad_state GPIB::2::INSTR: - device: device default \ No newline at end of file + device: device six + GPIB::3::INSTR: + device: device four \ No newline at end of file diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 51488e3a4d9..ba8de24da95 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -1,5 +1,5 @@ -import itertools import re +from itertools import product from typing import cast from qcodes import VisaInstrument, InstrumentChannel, ChannelList @@ -10,13 +10,27 @@ class LockAcquisitionError(Exception): pass +def cached_method(method): + def inner(self, *args, get_cached=False, **kwargs): + if not hasattr(self, "__cached_values__"): + self.__cached_values__ = {} + + if method not in self.__cached_values__ or not get_cached: + self.__cached_values__[method] = method(self, *args, **kwargs) + + return self.__cached_values__[method] + + return inner + + class S46Channel(InstrumentChannel): def __init__(self, parent, name, channel_number, relay_lock): super().__init__(parent, name) self._channel_number = channel_number self._relay_lock = relay_lock - if self._get_state() == "close": + + if self._get_state(get_cached=True) == "close": try: self._relay_lock.acquire(self._channel_number) except LockAcquisitionError as e: @@ -34,10 +48,9 @@ def __init__(self, parent, name, channel_number, relay_lock): vals=Enum("open", "close") ) - def _get_state(self): + def _get_state(self, get_cached=False): is_closed = self._channel_number in \ - self.root_instrument.get_closed_channel_numbers() - + self.parent.get_closed_channel_numbers(get_cached=get_cached) return {True: "close", False: "open"}[is_closed] def _set_state(self, new_state: str): @@ -77,19 +90,18 @@ def release(self, channel_number): class S46(VisaInstrument): - channel_aliases = dict( - zip([ - "{}{}".format(*a) - for a in itertools.product(["A", "B", "C", "D"], range(1, 7)) - ] + - [ - f"R{i}" for i in range(1, 9) - ], - range(1, 33)) - ) - relay_names = ["A", "B", "C", "D"] + [f"R{j}" for j in range(1, 9)] + _aliases_list = [ + f"{a}{b}" for a, b in product( + ["A", "B", "C", "D"], + list(range(1, 7)) + ) + ] + + _aliases_list += [f"R{i}" for i in range(1, 9)] + aliases = dict(zip(_aliases_list, range(1, 33))) + def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) @@ -101,7 +113,6 @@ def __init__(self, name, address, **kwargs): ) for relay_name, channel_count in zip(S46.relay_names, self.relay_layout): - relay_lock = RelayLock(relay_name) for channel_index in range(1, channel_count + 1): @@ -111,14 +122,15 @@ def __init__(self, name, address, **kwargs): else: alias = relay_name - channel_number = S46.channel_aliases[alias] + channel_number = S46.aliases[alias] channel = S46Channel(self, alias, channel_number, relay_lock) channels.append(channel) - self.add_submodule(channel.short_name, channel) + self.add_submodule(alias, channel) self.add_submodule("channels", channels) self.connect_message() + @cached_method def get_closed_channel_numbers(self): closed_channels_str = re.findall(r"\d+", self.ask(":CLOS?")) return [int(i) for i in closed_channels_str] @@ -136,4 +148,3 @@ def open_all_channels(self): @property def relay_layout(self): return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] - diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 4e7ebe8abcf..0989da2dfdf 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -10,8 +10,15 @@ @pytest.fixture(scope='module') -def s46(): - driver = S46('s46_sim',address='GPIB::2::INSTR', visalib=visalib) +def s46_six(): + driver = S46('s46_six',address='GPIB::2::INSTR', visalib=visalib) + yield driver + driver.close() + + +@pytest.fixture(scope='module') +def s46_four(): + driver = S46('s46_four',address='GPIB::3::INSTR', visalib=visalib) yield driver driver.close() @@ -25,49 +32,65 @@ def test_runtime_error_on_bad_init(): S46('s46_bad_state', address='GPIB::1::INSTR', visalib=visalib) -def test_init(s46): +def test_init_six(s46_six): - n_channels = len(s46.channels) + n_channels = len(s46_six.channels) assert n_channels == 26 - closed_channels = [0, 7, 12] + closed_channels = [1, 8, 13] + + for channel in s46_six.channels: + channel_nr = S46.aliases[channel.short_name] + state = "close" if channel_nr in closed_channels else "open" + assert channel.state() == state + + +def test_init_four(s46_four): - for channel_nr in range(n_channels): + n_channels = len(s46_four.channels) + assert n_channels == 18 + + closed_channels = [1, 8] + + for channel in s46_four.channels: + channel_nr = S46.aliases[channel.short_name] state = "close" if channel_nr in closed_channels else "open" - assert s46.channels[channel_nr].state() == state + assert channel.state() == state -def test_open_close(s46): +def test_open_close(s46_six): with pytest.raises( LockAcquisitionError, match="is already in use by channel" ): - s46.channels[1].state("close") + s46_six.channels[1].state("close") - s46.channels[0].state("open") - s46.channels[1].state("close") - s46.channels[18].state("close") + s46_six.channels[0].state("open") + s46_six.channels[1].state("close") + s46_six.channels[18].state("close") with pytest.raises( LockAcquisitionError, match="is already in use by channel" ): - s46.channels[19].state("close") + s46_six.channels[19].state("close") + +def alias_to_channel_nr(alias): + offset = dict(zip(["A", "B", "C", "D", "R"], range(0, 32, 6)))[alias[0]] + return offset + int(alias[1:]) -def test_aliases(s46): - hex_aliases = [ - f"{a}{b}" for a, b in product( - ["A", "B", "C", "D"], - list(range(1, 7)) - ) - ] +def test_aliases_six(s46_six): + for channel in s46_six.channels: + alias = channel.short_name + assert getattr(s46_six, alias) is channel + assert channel.channel_number == alias_to_channel_nr(alias) - aliases = hex_aliases + [f"R{i}" for i in range(1, 9)] - for channel in s46.channels: - idx = channel.channel_number - 1 - alias = aliases[idx] - assert getattr(s46, alias) is channel +def test_aliases_four(s46_four): + for channel in s46_four.channels: + alias = channel.short_name + assert getattr(s46_four, alias) is channel + assert channel.channel_number == alias_to_channel_nr(alias) From ce2fb0f12d32011b329e694d65e411d78b8e3f81 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 12:06:05 -0800 Subject: [PATCH 329/719] added test to assert that the 'close' query is only asked once during init --- .../QCodes example with Keithley S46.ipynb | 56 +++++++++++++++++++ qcodes/tests/drivers/test_keithley_s46.py | 17 +++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 6685d57991b..7418c8a49de 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -404,6 +404,62 @@ "s46.A1.state(\"open\")" ] }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "class A: \n", + " @property \n", + " def a(self): \n", + " return 1\n", + "\n", + "class B(A): \n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b = B()\n", + "b.a" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[1, 2, 3, 1].count(1)" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 0989da2dfdf..6821efd7b6c 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -1,5 +1,4 @@ import pytest -from itertools import product from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( S46, LockAcquisitionError @@ -9,16 +8,26 @@ visalib = sims.__file__.replace('__init__.py', 'Keithley_s46.yaml@sim') +class S46LoggedAsk(S46): + def __init__(self, *args, **kwargs): + self._ask_log = [] + super().__init__(*args, **kwargs) + + def ask(self, cmd: str): + self._ask_log.append(cmd) + return super().ask(cmd) + + @pytest.fixture(scope='module') def s46_six(): - driver = S46('s46_six',address='GPIB::2::INSTR', visalib=visalib) + driver = S46LoggedAsk('s46_six', address='GPIB::2::INSTR', visalib=visalib) yield driver driver.close() @pytest.fixture(scope='module') def s46_four(): - driver = S46('s46_four',address='GPIB::3::INSTR', visalib=visalib) + driver = S46LoggedAsk('s46_four', address='GPIB::3::INSTR', visalib=visalib) yield driver driver.close() @@ -33,6 +42,7 @@ def test_runtime_error_on_bad_init(): def test_init_six(s46_six): + assert s46_six._ask_log.count(":CLOS?") == 1 n_channels = len(s46_six.channels) assert n_channels == 26 @@ -46,6 +56,7 @@ def test_init_six(s46_six): def test_init_four(s46_four): + assert s46_four._ask_log.count(":CLOS?") == 1 n_channels = len(s46_four.channels) assert n_channels == 18 From 2834048afb331f071ffe5f386ecbc0954e3698ad Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Tue, 4 Dec 2018 09:50:16 +1100 Subject: [PATCH 330/719] Set timeout on server start --- qcodes/monitor/monitor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index b090709784a..41d37dbba77 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -133,7 +133,9 @@ def __init__(self, *parameters, interval=1): self.start() # Wait until the loop is running - self.server_is_started.wait() + self.server_is_started.wait(timeout=5) + if not self.server_is_started.is_set(): + raise RuntimeError("Failed to start server") Monitor.running = self def run(self): From 31bb84897cb56262738cc0c6fc00de930d10df1f Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Tue, 4 Dec 2018 11:21:12 +1100 Subject: [PATCH 331/719] Remove unused import --- qcodes/tests/test_monitor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qcodes/tests/test_monitor.py b/qcodes/tests/test_monitor.py index c17943e6cbe..b1832d0969e 100644 --- a/qcodes/tests/test_monitor.py +++ b/qcodes/tests/test_monitor.py @@ -3,7 +3,6 @@ """ from unittest import TestCase -import time import asyncio import json import random From f1e3852c10f6341071323cd9593e2a4bfc7d0580 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 16:29:44 -0800 Subject: [PATCH 332/719] docstrings + type hints --- .../QCodes example with Keithley S46.ipynb | 56 ------ .../tektronix/Keithley_s46.py | 171 +++++++++++++----- qcodes/tests/drivers/test_keithley_s46.py | 92 +++++++--- 3 files changed, 189 insertions(+), 130 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 7418c8a49de..6685d57991b 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -404,62 +404,6 @@ "s46.A1.state(\"open\")" ] }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "class A: \n", - " @property \n", - " def a(self): \n", - " return 1\n", - "\n", - "class B(A): \n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = B()\n", - "b.a" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[1, 2, 3, 1].count(1)" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index ba8de24da95..4c73c057680 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -1,8 +1,11 @@ +""" +Driver for the Tekronix S46 RF switch +""" import re from itertools import product -from typing import cast -from qcodes import VisaInstrument, InstrumentChannel, ChannelList +from typing import cast, Callable, Any, Union, Dict, List +from qcodes import Instrument, VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum @@ -10,8 +13,14 @@ class LockAcquisitionError(Exception): pass -def cached_method(method): - def inner(self, *args, get_cached=False, **kwargs): +def cached_method(method: Callable) -> Callable: + """ + A decorator which adds a keyword 'get_cached' to a method. When + 'get_cached=True', the decorated method returns a cached return value. If + the method has not been called before, or 'get_cached=False' the original + method is called. + """ + def inner(self, *args: Any, get_cached: bool=False, **kwargs: Any) -> Any: if not hasattr(self, "__cached_values__"): self.__cached_values__ = {} @@ -19,21 +28,73 @@ def inner(self, *args, get_cached=False, **kwargs): self.__cached_values__[method] = method(self, *args, **kwargs) return self.__cached_values__[method] - return inner +class RelayLock: + """ + The S46 either has six pole or a four pole relays. For example, channels + 'A1' to 'A6' are all on relay 'A'. However, channels 'R1' to 'R8' are all on + individual relays. + + Only one channel per relay may be closed at any given time to prevent + degradation of RF performance and even switch damage. See page 2-11 + of the manual. To enforce this, a lock mechanism has been implemented. + """ + def __init__(self, relay_name: str): + self.relay_name = relay_name + self._locked_by = None + + def acquire(self, channel_number: int): + """ + Request a lock acquisition + """ + if self._locked_by is not None and self._locked_by != channel_number: + raise LockAcquisitionError( + f"Relay {self.relay_name} is already in use by channel " + f"{self._locked_by}" + ) + else: + self._locked_by = channel_number + + def release(self, channel_number: int): + """ + Release a lock. + """ + if self._locked_by == channel_number: + self._locked_by = None + + class S46Channel(InstrumentChannel): - def __init__(self, parent, name, channel_number, relay_lock): + """ + A channel class for the S46 + + Args: + parent + name + channel_number: unlike other instruments, channel numbers on the + S46 will not be contiguous. That is, we may have channels 1, 2 and 4 + but channel 3 may be missing. + relay_lock: When closing the channel, request a lock acquisition. + Release the lock when opening + """ + def __init__( + self, + parent: Union[Instrument, 'InstrumentChannel'], + name: str, + channel_number: int, + relay_lock: RelayLock + ): super().__init__(parent, name) self._channel_number = channel_number self._relay_lock = relay_lock - - if self._get_state(get_cached=True) == "close": + # Acquire the lock if upon init we find the channel closed. + if self._get_state(init=True) == "close": try: self._relay_lock.acquire(self._channel_number) except LockAcquisitionError as e: + # another channel has already acquired the lock raise RuntimeError( "The driver is initialized from an undesirable instrument " "state where more then one channel on a single relay is " @@ -48,13 +109,23 @@ def __init__(self, parent, name, channel_number, relay_lock): vals=Enum("open", "close") ) - def _get_state(self, get_cached=False): - is_closed = self._channel_number in \ - self.parent.get_closed_channel_numbers(get_cached=get_cached) + def _get_state(self, init: bool=False) -> str: + """ + Args: + init: When calling this method from self.__init__, make this + value 'True'. This will prevent the instrument being queried + ':CLOS?' for each channel. + """ + closed_channels = self.parent.get_closed_channel_numbers( + get_cached=init) + + is_closed = self._channel_number in closed_channels return {True: "close", False: "open"}[is_closed] - def _set_state(self, new_state: str): - + def _set_state(self, new_state: str) -> None: + """ + Open/Close the channel + """ if new_state == "close": self._relay_lock.acquire(self._channel_number) elif new_state == "open": @@ -63,36 +134,15 @@ def _set_state(self, new_state: str): self.write(f":{new_state} (@{self._channel_number})") @property - def channel_number(self): + def channel_number(self) -> int: return self._channel_number -class RelayLock: - def __init__(self, relay_name): - self.relay_name = relay_name - self._locked_by = None - - def acquire(self, channel_number): - - if self._locked_by is not None and self._locked_by != channel_number: - raise LockAcquisitionError( - f"Relay {self.relay_name} is already in use by channel " - f"{self._locked_by}" - ) - else: - self._locked_by = channel_number - - def release(self, channel_number): - - if self._locked_by == channel_number: - self._locked_by = None - - class S46(VisaInstrument): - relay_names = ["A", "B", "C", "D"] + [f"R{j}" for j in range(1, 9)] + relay_names: list = ["A", "B", "C", "D"] + [f"R{j}" for j in range(1, 9)] - _aliases_list = [ + _aliases_list: list = [ f"{a}{b}" for a, b in product( ["A", "B", "C", "D"], list(range(1, 7)) @@ -100,9 +150,17 @@ class S46(VisaInstrument): ] _aliases_list += [f"R{i}" for i in range(1, 9)] - aliases = dict(zip(_aliases_list, range(1, 33))) + # Make a dictionary where keys are channel aliases (e.g. 'A1', 'B3', etc) + # and values are corresponding channel numbers. + aliases: Dict[str, int] = dict(zip(_aliases_list, range(1, 33))) + + def __init__( + self, + name: str, + address: str, + **kwargs: Any + ): - def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) channels = ChannelList( @@ -112,15 +170,18 @@ def __init__(self, name, address, **kwargs): snapshotable=False ) - for relay_name, channel_count in zip(S46.relay_names, self.relay_layout): + for relay_name, channel_count in zip( + S46.relay_names, self.relay_layout): + relay_lock = RelayLock(relay_name) for channel_index in range(1, channel_count + 1): - + # E.g. For channel 'B2', channel_index is 2 if channel_count > 1: alias = f"{relay_name}{channel_index}" else: - alias = relay_name + alias = relay_name # For channels R1 to R8, we have one + # channel per relay. Channel alias = relay name channel_number = S46.aliases[alias] channel = S46Channel(self, alias, channel_number, relay_lock) @@ -131,20 +192,36 @@ def __init__(self, name, address, **kwargs): self.connect_message() @cached_method - def get_closed_channel_numbers(self): + def get_closed_channel_numbers(self) -> List[int]: + """ + Query the instrument for closed channels. Add an option to return + a cached response so we can prevent this method from being called + repeatedly for each channel during initialization of the driver. + """ closed_channels_str = re.findall(r"\d+", self.ask(":CLOS?")) return [int(i) for i in closed_channels_str] - def get_closed_channels(self): + def get_closed_channels(self) -> List[S46Channel]: + """ + Return a list of closed channels as a list of channel objects + """ return [ channel for channel in self.channels if channel.channel_number in self.get_closed_channel_numbers() ] - def open_all_channels(self): + def open_all_channels(self) -> None: + """ + Please do not write ':OPEN ALL' to the instrument as this will + circumvent the lock. + """ for channel in self.get_closed_channels(): - cast(S46Channel, channel).state("open") + channel.state("open") @property - def relay_layout(self): + def relay_layout(self) -> List[int]: + """ + The relay layout tells us how many channels we have per relay. Note + that we can have zero channels per relay. + """ return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 6821efd7b6c..67a5862b884 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -8,7 +8,26 @@ visalib = sims.__file__.replace('__init__.py', 'Keithley_s46.yaml@sim') +def test_aliases_dict(): + """ + Test the class attribute 'aliases' which maps channel aliases + (e.g. A1, B2, etc) to channel numbers. + """ + def calc_channel_nr(alias: str) -> int: + """ + We perform the calculation in a different way to verify correctness + """ + offset_dict = dict(zip(["A", "B", "C", "D", "R"], range(0, 32, 6))) + return offset_dict[alias[0]] + int(alias[1:]) + + assert all([nr == calc_channel_nr(al) for al, nr in S46.aliases.items()]) + + class S46LoggedAsk(S46): + """ + A version of the driver which logs every ask command. We need this to + assert that ':CLOS?' is called once during initialization + """ def __init__(self, *args, **kwargs): self._ask_log = [] super().__init__(*args, **kwargs) @@ -20,6 +39,9 @@ def ask(self, cmd: str): @pytest.fixture(scope='module') def s46_six(): + """ + A six channel-per-relay instrument + """ driver = S46LoggedAsk('s46_six', address='GPIB::2::INSTR', visalib=visalib) yield driver driver.close() @@ -27,13 +49,20 @@ def s46_six(): @pytest.fixture(scope='module') def s46_four(): + """ + A four channel-per-relay instrument + """ driver = S46LoggedAsk('s46_four', address='GPIB::3::INSTR', visalib=visalib) yield driver driver.close() def test_runtime_error_on_bad_init(): - + """ + If we initialize the driver from an instrument state with more then one + channel per relay closed, raise a runtime error. An instrument can come to + this state if previously, other software was used to control the instrument + """ with pytest.raises( RuntimeError, match="The driver is initialized from an undesirable instrument state" @@ -42,9 +71,13 @@ def test_runtime_error_on_bad_init(): def test_init_six(s46_six): + """ + Test that the six channel instrument initializes correctly. + """ assert s46_six._ask_log.count(":CLOS?") == 1 n_channels = len(s46_six.channels) + # Channels A1 to D6 + R5 + R8 (4 * 6 + 2) assert n_channels == 26 closed_channels = [1, 8, 13] @@ -53,12 +86,17 @@ def test_init_six(s46_six): channel_nr = S46.aliases[channel.short_name] state = "close" if channel_nr in closed_channels else "open" assert channel.state() == state + assert channel_nr == S46.aliases[channel.short_name] def test_init_four(s46_four): + """ + Test that the six channel instrument initializes correctly. + """ assert s46_four._ask_log.count(":CLOS?") == 1 n_channels = len(s46_four.channels) + # Channels A1 to D4 + R5 + R8 (4 * 4 + 2) assert n_channels == 18 closed_channels = [1, 8] @@ -67,41 +105,41 @@ def test_init_four(s46_four): channel_nr = S46.aliases[channel.short_name] state = "close" if channel_nr in closed_channels else "open" assert channel.state() == state + assert channel_nr == S46.aliases[channel.short_name] + # A four channel instrument will have channels missing + for relay in ["A", "B", "C", "D"]: + for index in [5, 6]: + alias = f"{relay}{index}" + assert not hasattr(s46_four, alias) -def test_open_close(s46_six): +def test_locking_mechanism(s46_six): + """ + 1) Test that the lock acquisition error is raised if we try to close + more then once channel per replay + 2) Test that the lock is released when opening a channel that was closed + """ with pytest.raises( LockAcquisitionError, match="is already in use by channel" ): - s46_six.channels[1].state("close") - - s46_six.channels[0].state("open") - s46_six.channels[1].state("close") - s46_six.channels[18].state("close") - + # A1 should be closed already + s46_six.A2.state("close") + # release the lock + s46_six.A1.state("open") + # now we should be able to close A2 + s46_six.A2.state("close") + + # Let C1 acquire the lock + s46_six.C1.state("close") + # closing C2 should raise an error with pytest.raises( LockAcquisitionError, match="is already in use by channel" ): - s46_six.channels[19].state("close") - + s46_six.C2.state("close") -def alias_to_channel_nr(alias): - offset = dict(zip(["A", "B", "C", "D", "R"], range(0, 32, 6)))[alias[0]] - return offset + int(alias[1:]) - - -def test_aliases_six(s46_six): - for channel in s46_six.channels: - alias = channel.short_name - assert getattr(s46_six, alias) is channel - assert channel.channel_number == alias_to_channel_nr(alias) - - -def test_aliases_four(s46_four): - for channel in s46_four.channels: - alias = channel.short_name - assert getattr(s46_four, alias) is channel - assert channel.channel_number == alias_to_channel_nr(alias) + # Upon opening C1 we should be able to close C2 + s46_six.C1.state("open") + s46_six.C2.state("close") From 1e16106a9495384e8615081eaaaf5431c2e1ab9f Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Tue, 4 Dec 2018 12:13:09 +1100 Subject: [PATCH 333/719] Move parameter type check to initializer --- qcodes/monitor/monitor.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 41d37dbba77..117aa9f5842 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -44,10 +44,6 @@ def _get_metadata(*parameters) -> Dict[str, Any]: # group metadata by instrument metas = defaultdict(list) # type: dict for parameter in parameters: - # Check we have a list of parameters - if not isinstance(parameter, Parameter): - raise ValueError("{} is not a parameter".format(parameter)) - # Get the latest value from the parameter, respecting the max_val_age parameter meta = {} meta["value"] = str(parameter.get_latest()) @@ -118,6 +114,12 @@ def __init__(self, *parameters, interval=1): interval: How often one wants to refresh the values """ super().__init__() + + # Check that all values are valid parameters + for parameter in parameters: + if not isinstance(parameter, Parameter): + raise TypeError("We can only monitor QCodes Parameters") + self.loop = None self.server = None self._parameters = parameters From c9abbe41c4e34039e197576b5995921227d02c62 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 17:20:00 -0800 Subject: [PATCH 334/719] edit notebook meta data to stop exec on CI --- .../QCodes example with Keithley S46.ipynb | 276 +++++------------- .../tektronix/Keithley_s46.py | 2 +- 2 files changed, 75 insertions(+), 203 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 6685d57991b..2e9132e83a4 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -1,5 +1,22 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tektronix Keithley S46\n", + "\n", + "The S46 is an RF swicth with four relays \"A\" to \"D\". These relays either have four or six poles, depending on the instrument model. Each pole constitutes a channel and can either be \"open\" or \"closed\". Channel \"A1\" is attached to the first pole on relay \"A\", channel \"B2\" is attached to the second pole of relay \"B\", etc... \n", + "\n", + "Channels \"A1\" to \"D6\" are all \"normally open\". Only one channel per relay may be closed. \n", + "\n", + "Additionally, there are optionally eight relays \"R1\" to \"R8\" which are two pole relays. One pole is \"normally closed\" and the other \"normally open\". For these relays, we have one channel per relay, so \"R1\" is both a channel and a relay. Upon closing the channel, the normally open pole will close. \n", + "\n", + "In this notebook, we have verified with a multi-meter that channels indeed open and close as expected. \n", + "\n", + "Note: We have performed tests with a six pole instrument. Although it is expected that this driver should work with a four pole instrument, this has not been verified due to a lack of instrument availability " + ] + }, { "cell_type": "code", "execution_count": 1, @@ -18,7 +35,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.62s\n" + "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.54s\n" ] } ], @@ -34,7 +51,7 @@ { "data": { "text/plain": [ - "[]" + "26" ] }, "execution_count": 3, @@ -43,32 +60,32 @@ } ], "source": [ - "s46.get_closed_channels()" + "len(s46.channels)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "26" + "[]" ] }, - "execution_count": 4, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "len(s46.channels)" + "s46.get_closed_channels()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -77,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -86,7 +103,7 @@ "'open'" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -97,7 +114,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -106,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -115,7 +132,7 @@ "'close'" ] }, - "execution_count": 8, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -124,251 +141,119 @@ "s46.A1.state()" ] }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('Relay A is already in use by channel 1', 'setting s2_A2_state to close')\n" - ] - } - ], - "source": [ - "try: \n", - " s46.A2.state(\"close\")\n", - " raise(\"We should not be here\")\n", - "except LockAcquisitionError as e: \n", - " print(e)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "s46.A1.state(\"open\")" - ] - }, { "cell_type": "code", "execution_count": 11, "metadata": {}, - "outputs": [], - "source": [ - "s46.A2.state(\"close\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "s46.A2.state(\"open\")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "assert s46.A1 is s46.channels[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "assert s46.A2 is s46.channels[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "assert s46.B1 is s46.channels[6]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'B1'" + "[]" ] }, - "execution_count": 16, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.channels[6].short_name" + "s46.get_closed_channels()" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Relay A is already in use by channel 1', 'setting s2_A2_state to close')\n" + ] + } + ], "source": [ - "s46.A1.state(\"close\")" + "try: \n", + " s46.A2.state(\"close\")\n", + " raise(\"We should not be here\")\n", + "except LockAcquisitionError as e: \n", + " print(e)" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ - "s46.B1.state(\"close\")" + "s46.A1.state(\"open\")" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ - "s46.R8.state(\"close\")" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ,\n", - " ]" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s46.get_closed_channels()" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 7, 32]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s46.get_closed_channel_numbers()" + "s46.A2.state(\"close\")" ] }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1\n", - "7\n", - "32\n" + "('Relay A is already in use by channel 2', 'setting s2_A1_state to close')\n" ] } ], "source": [ - "print(S46.alias_to_channel_number(\"A1\"))\n", - "print(S46.alias_to_channel_number(\"B1\"))\n", - "print(S46.alias_to_channel_number(\"R8\"))" + "try: \n", + " s46.A1.state(\"close\")\n", + " raise(\"We should not be here\")\n", + "except LockAcquisitionError as e: \n", + " print(e)" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ - "def channel_number_to_alias(num): \n", - " n = num - 24\n", - " if n > 0: \n", - " return f\"R{n}\"\n", - " index = num % 6\n", - " relay = {0: \"A\", 1: \"B\", 2: \"C\", 3: \"D\"}[(num - 1)//6]\n", - " return f\"{relay}{index}\"" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A1\n", - "B1\n", - "R8\n" - ] - } - ], - "source": [ - "print(channel_number_to_alias(1))\n", - "print(channel_number_to_alias(7))\n", - "print(channel_number_to_alias(32))" + "s46.B1.state(\"close\")" ] }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "A2\n", - "B2\n", - "R7\n" + "('Relay B is already in use by channel 7', 'setting s2_B2_state to close')\n" ] } ], "source": [ - "print(channel_number_to_alias(2))\n", - "print(channel_number_to_alias(8))\n", - "print(channel_number_to_alias(31))" + "try: \n", + " s46.B2.state(\"close\")\n", + " raise(\"We should not be here\")\n", + "except LockAcquisitionError as e: \n", + " print(e)" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -377,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -386,7 +271,7 @@ "[]" ] }, - "execution_count": 27, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -394,22 +279,6 @@ "source": [ "s46.get_closed_channels()" ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "s46.A1.state(\"open\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -429,6 +298,9 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.7" + }, + "nbsphinx": { + "execute": "never" } }, "nbformat": 4, diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 4c73c057680..30a1362b394 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -43,7 +43,7 @@ class RelayLock: """ def __init__(self, relay_name: str): self.relay_name = relay_name - self._locked_by = None + self._locked_by: int = None def acquire(self, channel_number: int): """ From c4bbc08d12accff0342545821ce244ea5e0d7f4f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 17:20:39 -0800 Subject: [PATCH 335/719] remove unused cast import --- qcodes/instrument_drivers/tektronix/Keithley_s46.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 30a1362b394..cbf02769321 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -4,7 +4,7 @@ import re from itertools import product -from typing import cast, Callable, Any, Union, Dict, List +from typing import Callable, Any, Union, Dict, List from qcodes import Instrument, VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum From ac173596cb1bd7e306deb7793592608387db98cb Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 17:28:43 -0800 Subject: [PATCH 336/719] add newline in simulation yaml --- qcodes/instrument/sims/Keithley_s46.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/sims/Keithley_s46.yaml b/qcodes/instrument/sims/Keithley_s46.yaml index 66f9789933d..4e3de706d37 100644 --- a/qcodes/instrument/sims/Keithley_s46.yaml +++ b/qcodes/instrument/sims/Keithley_s46.yaml @@ -80,4 +80,4 @@ resources: GPIB::2::INSTR: device: device six GPIB::3::INSTR: - device: device four \ No newline at end of file + device: device four From 84f382643a67df1b118acf2b032f24b70d88be40 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 17:29:44 -0800 Subject: [PATCH 337/719] wrong comment in simulation yaml file --- qcodes/instrument/sims/Keithley_s46.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/sims/Keithley_s46.yaml b/qcodes/instrument/sims/Keithley_s46.yaml index 4e3de706d37..2f2b6a840d1 100644 --- a/qcodes/instrument/sims/Keithley_s46.yaml +++ b/qcodes/instrument/sims/Keithley_s46.yaml @@ -1,4 +1,4 @@ -# SIMULATED INSTRUMENT FOR Keysight 33xxx series function generator +# SIMULATED INSTRUMENT FOR Keysight S46 RF switch spec: "1.0" devices: device bad_state: From 0b453b55d08906cf4eb08936e18f1180296cf989 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 17:38:13 -0800 Subject: [PATCH 338/719] remove nonsense assert from test --- qcodes/tests/drivers/test_keithley_s46.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 67a5862b884..72e0db48645 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -86,7 +86,6 @@ def test_init_six(s46_six): channel_nr = S46.aliases[channel.short_name] state = "close" if channel_nr in closed_channels else "open" assert channel.state() == state - assert channel_nr == S46.aliases[channel.short_name] def test_init_four(s46_four): @@ -105,7 +104,6 @@ def test_init_four(s46_four): channel_nr = S46.aliases[channel.short_name] state = "close" if channel_nr in closed_channels else "open" assert channel.state() == state - assert channel_nr == S46.aliases[channel.short_name] # A four channel instrument will have channels missing for relay in ["A", "B", "C", "D"]: From f499cb7c239d0ec18fc8dfc45e8388ff540b4dc9 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Mon, 3 Dec 2018 18:00:17 -0800 Subject: [PATCH 339/719] explicitly test channel number invariance --- qcodes/tests/drivers/test_keithley_s46.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 72e0db48645..5a38c5dc91e 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -112,6 +112,19 @@ def test_init_four(s46_four): assert not hasattr(s46_four, alias) +def test_channel_number_invariance(s46_four, s46_six): + """ + Regardless of the channel layout (that is, number of channels per relay), + channel aliases should represent the same channel. See also page 2-5 of the + manual (e.g. B1 is *always* channel 7) + """ + for alias in S46.aliases.keys(): + if hasattr(s46_four, alias) and hasattr(s46_six, alias): + channel_four = getattr(s46_four, alias) + channel_six = getattr(s46_six, alias) + assert channel_four.channel_number == channel_six.channel_number + + def test_locking_mechanism(s46_six): """ 1) Test that the lock acquisition error is raised if we try to close From 8d91bb181a0867bf25a7721ea1d2db8eefc10935 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Tue, 4 Dec 2018 14:10:08 +1100 Subject: [PATCH 340/719] Set reasonable timeouts on waiting for clients to disconnect --- qcodes/monitor/monitor.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 117aa9f5842..060bc8d5905 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -148,7 +148,8 @@ def run(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) try: - server_start = websockets.serve(self.handler, '127.0.0.1', WEBSOCKET_PORT) + server_start = websockets.serve(self.handler, '127.0.0.1', + WEBSOCKET_PORT, close_timeout=1) self.server = self.loop.run_until_complete(server_start) self.server_is_started.set() self.loop.run_forever() @@ -182,13 +183,13 @@ def stop(self) -> None: Monitor.running = None async def __stop_server(self): - log.debug("asking server to close") + log.debug("asking server %r to close", self.server) self.server.close() log.debug("waiting for server to close") await self.loop.create_task(self.server.wait_closed()) log.debug("stopping loop") log.debug("Pending tasks at stop: %r", - asyncio.Task.all_tasks(self.loop)) + asyncio.Task.all_tasks(self.loop)) self.loop.stop() def join(self, timeout=None) -> None: @@ -208,7 +209,9 @@ def join(self, timeout=None) -> None: # the above may throw a runtime error if the loop is already # stopped in which case there is nothing more to do log.exception("Could not close loop") - self.loop_is_closed.wait() + self.loop_is_closed.wait(timeout=5) + if not self.loop_is_closed.is_set(): + raise RuntimeError("Failed to join loop") log.debug("Loop reported closed") super().join(timeout=timeout) log.debug("Monitor Thread has joined") From 5f0aa3d4f352a54881101345284e4d8be230495a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 4 Dec 2018 14:16:28 +0100 Subject: [PATCH 341/719] support for expaning scalar parameters --- qcodes/dataset/sqlite_base.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 792e21ca5d4..5a47cb871a5 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1461,18 +1461,27 @@ def get_data_of_param_and_deps_as_columns(conn: ConnectionPlus, res = get_data(conn, table_name, columns, start=start, end=end) - if 'array' in types and 'numeric' in types: # todo handle str + if 'array' in types and ('numeric' in types or 'text' in types): # todo: Should we check that all the arrays are the same size? first_array_element = types.index('array') - non_array_elements = [i for i, x in enumerate(types) - if x == "numeric"] - for dat in res: - for element in non_array_elements: - dat[element] = np.zeros_like(dat[first_array_element]) \ - + dat[element] + numeric_elms = [i for i, x in enumerate(types) + if x == "numeric"] + text_elms = [i for i, x in enumerate(types) + if x == "text"] + for row in res: + for element in numeric_elms: + row[element] = np.full_like(row[first_array_element], + row[element], + dtype=np.float) + # todo should we handle int/float types here + for element in text_elms: + strlen = len(row[element]) + row[element] = np.full_like(row[first_array_element], + row[element], + dtype=f'U{strlen}') res_t = list(map(list, zip(*res))) - output[param] = {name: np.array(column_data) + output[param] = {name: np.squeeze(np.array(column_data)) for name, column_data in zip(columns, res_t)} return output From 81b04ab75ff0ddcced828a4ba2dfdc28be254e4a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 4 Dec 2018 14:17:00 +0100 Subject: [PATCH 342/719] Improve tests --- qcodes/tests/dataset/dataset_fixtures.py | 34 ++++--- qcodes/tests/dataset/test_dataset_basic.py | 101 +++++++++++++++++++-- 2 files changed, 112 insertions(+), 23 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index 0493fb65840..dd6729244c6 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -33,11 +33,12 @@ def scalar_dataset(dataset): yield dataset -@pytest.fixture -def array_dataset(experiment): +@pytest.fixture(scope="function", + params=["array", "numeric"]) +def array_dataset(experiment, request): meas = Measurement() param = ArraySetPointParam() - meas.register_parameter(param) + meas.register_parameter(param, paramtype=request.param) with meas.run() as datasaver: datasaver.add_result((param, param.get(),)) @@ -47,13 +48,13 @@ def array_dataset(experiment): datasaver.dataset.conn.close() - -@pytest.fixture -def multi_dataset(experiment): +@pytest.fixture(scope="function", + params=["array", "numeric"]) +def multi_dataset(experiment, request): meas = Measurement() param = Multi2DSetPointParam() - meas.register_parameter(param) + meas.register_parameter(param, paramtype=request.param) with meas.run() as datasaver: datasaver.add_result((param, param.get(),)) @@ -62,13 +63,16 @@ def multi_dataset(experiment): finally: datasaver.dataset.conn.close() -@pytest.fixture -def array_in_scalar_dataset(experiment): + +@pytest.fixture(scope="function", + params=["array", "numeric"]) +def array_in_scalar_dataset(experiment, request): meas = Measurement() scalar_param = Parameter('scalarparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param) - meas.register_parameter(param, setpoints=(scalar_param,)) + meas.register_parameter(param, setpoints=(scalar_param,), + paramtype=request.param) with meas.run() as datasaver: for i in range(1, 10): @@ -81,13 +85,15 @@ def array_in_scalar_dataset(experiment): datasaver.dataset.conn.close() -@pytest.fixture -def array_in_str_dataset(experiment): +@pytest.fixture(scope="function", + params=["array", "numeric"]) +def array_in_str_dataset(experiment, request): meas = Measurement() - scalar_param = Parameter('scalarparam', set_cmd=None) + scalar_param = Parameter('textparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param, paramtype='text') - meas.register_parameter(param, setpoints=(scalar_param,)) + meas.register_parameter(param, setpoints=(scalar_param,), + paramtype=request.param) with meas.run() as datasaver: for i in ['A', 'B', 'C']: diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index ea81bb0dd12..061c476e1b9 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1,7 +1,7 @@ import itertools from copy import copy import re - +from typing import Sequence, Tuple import pytest import numpy as np @@ -765,19 +765,86 @@ def test_get_parameter_data(scalar_dataset): def test_get_array_parameter_data(array_dataset): - parameter_test_helper(array_dataset) + paramspecs = array_dataset.paramspecs + types = [param.type for param in paramspecs.values()] + + if 'array' not in types: + parameter_test_helper(array_dataset) + + inputnames = ['testparameter'] + data = array_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + assert len(data.keys()) == len(inputnames) + expected_names = {} + expected_names['testparameter'] = ['testparameter', 'this_setpoint'] + expected_shapes = {} + expected_shapes['testparameter'] = [(5, ), (5, )] + + verify_data_dict(data, inputnames, expected_names, expected_shapes) def test_get_multi_parameter_data(multi_dataset): - parameter_test_helper(multi_dataset) + paramspecs = multi_dataset.paramspecs + types = [param.type for param in paramspecs.values()] + + if 'array' not in types: + parameter_test_helper(multi_dataset) + + inputnames = ['this', 'that'] + data = multi_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + assert len(data.keys()) == len(inputnames) + expected_names = {} + expected_names['this'] = ['this', 'this_setpoint', 'that_setpoint'] + expected_names['that'] = ['that', 'this_setpoint', 'that_setpoint'] + expected_shapes = {} + if 'array' in types: + expected_shapes['this'] = [(5, 3), (5, 3)] + expected_shapes['that'] = [(5, 3), (5, 3)] + else: + expected_shapes['this'] = [(15,), (15,)] + expected_shapes['that'] = [(15,), (15,)] + verify_data_dict(data, inputnames, expected_names, expected_shapes) def test_get_array_in_scalar_param_data(array_in_scalar_dataset): - parameter_test_helper(array_in_scalar_dataset) + paramspecs = array_in_scalar_dataset.paramspecs + types = [param.type for param in paramspecs.values()] + + if 'array' not in types: + parameter_test_helper(array_in_scalar_dataset) + + inputnames = ['testparameter'] + data = array_in_scalar_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + assert len(data.keys()) == len(inputnames) + expected_names = {} + expected_names['testparameter'] = ['testparameter', 'scalarparam', + 'this_setpoint'] + expected_shapes = {} + if 'array' in types: + expected_shapes['testparameter'] = [(9, 5), (9, 5)] + else: + expected_shapes['testparameter'] = [(45,), (45,)] + verify_data_dict(data, inputnames, expected_names, expected_shapes) def test_get_array_in_str_param_data(array_in_str_dataset): - parameter_test_helper(array_in_str_dataset) + paramspecs = array_in_str_dataset.paramspecs + types = [param.type for param in paramspecs.values()] + + if 'array' not in types: + parameter_test_helper(array_in_str_dataset) + + inputnames = ['testparameter'] + data = array_in_str_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + assert len(data.keys()) == len(inputnames) + expected_names = {} + expected_names['testparameter'] = ['testparameter', 'textparam', + 'this_setpoint'] + expected_shapes = {} + if 'array' in types: + expected_shapes['testparameter'] = [(3, 5), (3, 5)] + else: + expected_shapes['testparameter'] = [(15,), (15,)] + verify_data_dict(data, inputnames, expected_names, expected_shapes) def parameter_test_helper(ds): @@ -788,14 +855,16 @@ def parameter_test_helper(ds): param_names = copy(params) params[0] = ds.paramspecs[params[0]] + + ref = ds.get_data(*params) dut = ds.get_parameter_data(*params) column_lengths = [] for col in dut.values(): column_lengths.append(col.size) - column_lenghts = np.array(column_lengths) - assert np.all(column_lenghts == column_lenghts[0]) + column_lengths = np.array(column_lengths) + assert np.all(column_lengths == column_lengths[0]) for i_row, row in enumerate(ref): for i_param, param_name in enumerate(param_names): @@ -813,5 +882,19 @@ def parameter_test_helper(ds): elif isinstance(v_ref, str): assert isinstance(v_test, np.str_) assert v_ref == v_test - else: - raise RuntimeError('Unsupported data type') + + +def verify_data_dict(data, parameter_names, expected_names, + expected_shapes): + for param in parameter_names: + innerdata = data[param] + verify_data_dict_for_single_param(innerdata, + expected_names[param], + expected_shapes[param]) + + +def verify_data_dict_for_single_param(datadict, + names: Sequence[str], + shapes: Sequence[Tuple[int, ...]]): + for name, shape in zip(names, shapes): + assert datadict[name].shape == shape From 5c0af86c7ff0c6a182e527c5c94c9a37607a5b86 Mon Sep 17 00:00:00 2001 From: nyxus Date: Tue, 4 Dec 2018 15:32:09 +0100 Subject: [PATCH 343/719] RTO1024: Add measurment and run continues commands; Added error count and next; corrected the stop_opc and opc paramaters; Added trigger mode paramater and added docstring to High defintion mode --- .../rohde_schwarz/RTO1000.py | 180 +++++++++++++++++- 1 file changed, 177 insertions(+), 3 deletions(-) diff --git a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py index cfa4a23ad04..1112920028e 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py +++ b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py @@ -129,6 +129,146 @@ def get_raw(self): return output +class ScopeMeasurement(InstrumentChannel): + """ + Class to hold a mesurement of the scope + """ + + def __init__(self, parent: Instrument, name: str, meas_nr: int): + """ + Args: + parent: The instrument to which the channel is attached + name: The name of the mesurement + meas_nr: The number of the mesurment in question. Must match the + actual number as used by the instrument (1..8) + """ + + if meas_nr not in range(1, 9): + raise ValueError('Invalid measurement number; Min: 1, max 8') + + self.meas_nr = meas_nr + super().__init__(parent, name) + + self.sources = vals.Enum('C1W1', 'C1W2', 'C1W3', + 'C2W1', 'C2W2', 'C2W3', + 'C3W1', 'C3W2', 'C3W3', + 'C4W1', 'C4W2', 'C4W3', + 'M1', 'M2', 'M3', 'M4', + 'R1', 'R2', 'R3', 'R4', + 'SBUS1', 'SBUS2', 'SBUS3', 'SBUS4', + 'D0', 'D1', 'D2', 'D3', + 'D4', 'D5', 'D6', 'D7', + 'D8', 'D9', 'D10', 'D11', + 'D12', 'D13', 'D14', 'D15', + 'TRK1', 'TRK2', 'TRK3', 'TRK4', + 'TRK5', 'TRK6', 'TRK7', 'TRK8', + 'SG1TL1', 'SG1TL2', + 'SG2TL1', 'SG2TL2', + 'SG3TL1', 'SG3TL2', + 'SG4TL1', 'SG4TL2', + 'Z1V1', 'Z1V2', 'Z1V3', 'Z1V4', + 'Z1I1', 'Z1I2', 'Z1I3', 'Z1I4', + 'Z2V1', 'Z2V2', 'Z2V3', 'Z2V4', + 'Z2I1', 'Z2I2', 'Z2I3', 'Z2I4') + + self.categories = vals.Enum('AMPTime', 'JITTer', 'EYEJitter', 'SPECtrum', + 'HISTogram', 'PROTocol') + + self.meas_type = vals.Enum( + # Amplitude/time measurements + 'HIGH', 'LOW', 'AMPLitude', 'MAXimum', + 'MINimum', 'PDELta', 'MEAN', 'RMS', + 'STDDev', 'POVershoot', 'NOVershoot', 'AREA', + 'RTIMe', 'FTIMe', 'PPULse', 'NPULse', + 'PERiod', 'FREQuency', 'PDCYcle', 'NDCYcle', + 'CYCarea', 'CYCMean', 'CYCRms', 'CYCStddev', + 'PULCnt', 'DELay', 'PHASe', 'BWIDth', + 'PSWitching', 'NSWitching', 'PULSetrain', 'EDGecount', + 'SHT', 'SHR', 'DTOTrigger', 'PROBemeter', + 'SLERising', 'SLEFalling' + # Jitter measurements + 'CCJitter', 'NCJitter', 'CCWidth', 'CCDutycycle', + 'TIE', 'UINTerval', 'DRATe', 'SKWDelay', + 'SKWPhase', + # Eye diagram measurements + 'ERPercent', 'ERDB', 'EHEight', 'EWIDth', + 'ETOP', 'EBASe', 'QFACtor', 'RMSNoise', + 'SNRatio', 'DCDistortion', 'ERTime', 'EFTime', + 'EBRate', 'EAMPlitude', 'PPJitter', 'STDJitter', + 'RMSJitter', + # Spectrum measurements + 'CPOWer', 'OBWidth', 'SBWidth', 'THD', + 'THDPCT', 'THDA', 'THDU', 'THDR', + 'HAR', 'PLISt', + # Histogram measurements + 'WCOunt', 'WSAMples', 'HSAMples', 'HPEak', + 'PEAK', 'UPEakvalue', 'LPEakvalue', 'HMAXimum', + 'HMINimum', 'MEDian', 'MAXMin', 'HMEan', + 'HSTDdev', 'M1STddev', 'M2STddev', 'M3STddev', + 'MKPositive', 'MKNegative' + ) + + self.add_parameter('enable', + label='Measurement {} enable'.format(meas_nr), + set_cmd='MEASurement{}:ENABle {{}}'.format(meas_nr), + vals=vals.Enum('ON', 'OFF'), + docstring='Switches the mesurment on or off') + + self.add_parameter('source', + label='Measurement {} source'.format(meas_nr), + set_cmd='MEASurement{}:SOURce {{}}'.format(meas_nr), + vals=self.sources, + docstring='Set the source of a measurement if the ' \ + 'measurement only needs one source') + + self.add_parameter('source_first', + label='Measurement {} first source'.format(meas_nr), + set_cmd='MEASurement{}:FSRC {{}}'.format(meas_nr), + vals=self.sources, + docstring='Set the first source of a measurement if the ' \ + 'measurement only needs mutliple sources') + + self.add_parameter('source_second', + label='Measurement {} second source'.format(meas_nr), + set_cmd='MEASurement{}:SSRC {{}}'.format(meas_nr), + vals=self.sources, + docstring='Set the second source of a measurement if the ' \ + 'measurement only needs mutliple sources') + + self.add_parameter('category', + label='Measurement {} category'.format(meas_nr), + set_cmd='MEASurement{}:CATegory {{}}'.format(meas_nr), + vals=self.categories, + docstring='Set the category of a measurement') + + self.add_parameter('main', + label='Measurement {} main'.format(meas_nr), + set_cmd='MEASurement{}:MAIN {{}}'.format(meas_nr), + vals=self.meas_type, + docstring='Set the main of a measurement') + + self.add_parameter('statistics_enable', + label='Measurement {} enable statistics'.format(meas_nr), + set_cmd='MEASurement{}:STATistics:ENABle {{}}'.format(meas_nr), + vals=vals.Enum('ON', 'OFF'), + docstring='Switches the mesurment on or off') + + self.add_parameter('clear', + label='Measurement {} clear statistics'.format(meas_nr), + set_cmd='MEASurement{}:CLEar'.format(meas_nr), + docstring='Clears/reset measurement') + + self.add_parameter('event_count', + label='Measurement {} number of events'.format(meas_nr), + get_cmd='MEASurement{}:RESult:EVTCount?'.format(meas_nr), + get_parser=int, + docstring='Number of measurement results in the long-term measurement') + + self.add_parameter('result_avg', + label='Measurement {} averages'.format(meas_nr), + get_cmd='MEASurement{}:RESult:AVG?'.format(meas_nr), + get_parser=float, + docstring='Average of the long-term measurement results') class ScopeChannel(InstrumentChannel): """ @@ -335,6 +475,7 @@ def __init__(self, name: str, address: str, # Now assign model-specific values self.num_chans = int(self.model[-1]) + self.num_meas = 8 self._horisontal_divs = int(self.ask('TIMebase:DIVisions?')) @@ -367,6 +508,18 @@ def __init__(self, name: str, address: str, 'CH4': 'CHAN4', 'EXT': 'EXT'}) + self.add_parameter('trigger_mode', + label='Trigger mode', + set_cmd='TRIGger:MODE {}', + get_cmd='TRIGger1:SOURce?', + val_mapping={'AUTO': 'AUTO', + 'NORMAL': 'NORMal', + 'FREERUN': 'FREerun'}, + docstring='Sets the trigger mode which determines the ' \ + ' behaviour of the instrument if no trigger occurs.\n' \ + 'Options: AUTO, NORMAL, FREERUN.', + unit='none') + self.add_parameter('trigger_type', label='Trigger type', set_cmd='TRIGger1:TYPE {}', @@ -488,7 +641,12 @@ def __init__(self, name: str, address: str, label='High definition (16 bit) state', set_cmd=self._set_hd_mode, get_cmd='HDEFinition:STAte?', - val_mapping={'ON': 1, 'OFF': 0}) + val_mapping={'ON': 1, 'OFF': 0}, + docstring='Sets the filter bandwidth for the high definition mode.\n' \ + 'ON: high definition mode, up to 16 bit digital resolution\n' \ + 'Options: ON, OFF\n\n' \ + 'Warning/Bug: By opening the HD acquisition menu on the scope, ' \ + 'this value will be set to "ON"') self.add_parameter('high_definition_bandwidth', label='High definition mode bandwidth', @@ -498,15 +656,31 @@ def __init__(self, name: str, address: str, get_parser=float, vals=vals.Numbers(1e4, 1e9)) + self.add_parameter('error_count', + label='Number of errors in the error stack', + get_cmd='SYSTem:ERRor:COUNt?', + unit='#', + get_parser=int) + + self.add_parameter('error_next', + label='Next error from the error stack', + get_cmd='SYSTem:ERRor:NEXT?', + get_parser=str) + # Add the channels to the instrument for ch in range(1, self.num_chans+1): chan = ScopeChannel(self, 'channel{}'.format(ch), ch) self.add_submodule('ch{}'.format(ch), chan) + for meas in range(1, self.num_meas+1): + measCh = ScopeMeasurement(self, 'measurement{}'.format(meas), meas) + self.add_submodule('meas{}'.format(meas), measCh) + self.add_function('stop', call_cmd='STOP') self.add_function('reset', call_cmd='*RST') - self.add_function('opc', call_cmd='*OPC?') - self.add_function('stop_opc', call_cmd='*STOP;OPC?') + self.add_parameter('opc', get_cmd='*OPC?') + self.add_parameter('stop_opc', get_cmd='STOP;*OPC?') + self.add_function('run_continues', call_cmd='RUNContinous') # starts the shutdown of the system self.add_function('system_shutdown', call_cmd='SYSTem:EXIT') From 52ffd702092465b76d7cae8c0e4977c6e645e1ff Mon Sep 17 00:00:00 2001 From: spxtr Date: Tue, 4 Dec 2018 12:38:29 -0800 Subject: [PATCH 344/719] Fix change_sensitivity in SR830 driver. --- qcodes/instrument_drivers/stanford_research/SR830.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/stanford_research/SR830.py b/qcodes/instrument_drivers/stanford_research/SR830.py index 89fd6ac7e1a..f7e47bb8ff0 100644 --- a/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/qcodes/instrument_drivers/stanford_research/SR830.py @@ -572,7 +572,7 @@ def decrement_sensitivity(self): def _change_sensitivity(self, dn): _ = self.sensitivity.get() - n = self.sensitivity.raw_value + n = int(self.sensitivity.raw_value) if self.input_config() in ['a', 'a-b']: n_to = self._N_TO_VOLT else: From 70902becdca13f31703ff11ae4ee814c646d7bd1 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 4 Dec 2018 13:34:46 -0800 Subject: [PATCH 345/719] minor improvement in dict comprehension --- .../instrument_drivers/tektronix/Keithley_s46.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index cbf02769321..06ead1f73c6 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -142,17 +142,15 @@ class S46(VisaInstrument): relay_names: list = ["A", "B", "C", "D"] + [f"R{j}" for j in range(1, 9)] - _aliases_list: list = [ - f"{a}{b}" for a, b in product( - ["A", "B", "C", "D"], - list(range(1, 7)) - ) - ] - - _aliases_list += [f"R{i}" for i in range(1, 9)] # Make a dictionary where keys are channel aliases (e.g. 'A1', 'B3', etc) # and values are corresponding channel numbers. - aliases: Dict[str, int] = dict(zip(_aliases_list, range(1, 33))) + aliases: Dict[str, int] = { + f"{a}{b}": count + 1 for count, (a, b) in enumerate(product( + ["A", "B", "C", "D"], + range(1, 7) + )) + } + aliases.update({f"R{i}": i + 24 for i in range(1, 9)}) def __init__( self, From 678ac1274b4b2dea70101f602c5c0b4ee39c5bd3 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 10:39:29 +1100 Subject: [PATCH 346/719] Fix error in get_timestamp docstring --- qcodes/instrument/parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index f70466d83b4..3ed741b9cb8 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -1364,7 +1364,7 @@ def get(self): else: return state['value'] - def get_timestamp(self): + def get_timestamp(self) -> datetime: """ Return the age of the last get_latest call. """ From f4283cd0e704490f9944485fe12a609a142544eb Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 10:39:53 +1100 Subject: [PATCH 347/719] Add extra info to errors/logs --- qcodes/monitor/monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index 060bc8d5905..faf4d3208de 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -93,7 +93,7 @@ async def server_func(websocket, path): # Wait for interval seconds and then send again await asyncio.sleep(interval) except (CancelledError, websockets.exceptions.ConnectionClosed): - log.debug("Got CancelledError or ConnectionClosed") + log.debug("Got CancelledError or ConnectionClosed", exc_info=True) break log.debug("Closing websockets connection") @@ -118,7 +118,7 @@ def __init__(self, *parameters, interval=1): # Check that all values are valid parameters for parameter in parameters: if not isinstance(parameter, Parameter): - raise TypeError("We can only monitor QCodes Parameters") + raise TypeError(f"We can only monitor QCodes Parameters, not {type(parameter)}") self.loop = None self.server = None From aa530985046f93d685408aa8425c9c7724dac087 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 10:40:25 +1100 Subject: [PATCH 348/719] Add test for get_latest/timestamp --- qcodes/tests/test_parameter.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/qcodes/tests/test_parameter.py b/qcodes/tests/test_parameter.py index f7deac8c177..4ed3c068708 100644 --- a/qcodes/tests/test_parameter.py +++ b/qcodes/tests/test_parameter.py @@ -6,6 +6,7 @@ from unittest import TestCase from typing import Tuple import pytest +from datetime import datetime import numpy as np from hypothesis import given, event, settings @@ -181,6 +182,22 @@ def test_snapshot_value(self): snap = p_no_snapshot.snapshot() self.assertNotIn('value', snap) + def test_get_latest(self): + # Create a gettable parameter + local_parameter = Parameter('test_param', set_cmd=None, get_cmd=None) + before_set = datetime.now() + local_parameter.set(1) + after_set = datetime.now() + + # Check we return last set value, with the correct timestamp + self.assertEqual(local_parameter.get_latest(), 1) + self.assertTrue(before_set < local_parameter.get_latest.get_timestamp() < after_set) + + # Check that updating the value updates the timestamp + local_parameter.set(2) + self.assertEqual(local_parameter.get_latest(), 2) + self.assertGreater(local_parameter.get_latest.get_timestamp(), after_set) + def test_has_set_get(self): # Create parameter that has no set_cmd, and get_cmd returns last value gettable_parameter = Parameter('one', set_cmd=False, get_cmd=None) From f38d68bb0e1b5d2399c311f130b7c88eee363b07 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 10:54:01 +1100 Subject: [PATCH 349/719] Update get_latest docstring --- qcodes/instrument/parameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument/parameter.py b/qcodes/instrument/parameter.py index 3ed741b9cb8..e48410a09b3 100644 --- a/qcodes/instrument/parameter.py +++ b/qcodes/instrument/parameter.py @@ -1366,7 +1366,7 @@ def get(self): def get_timestamp(self) -> datetime: """ - Return the age of the last get_latest call. + Return the age of the latest parameter value. """ state = self.parameter._latest return state["ts"] From b23810a9f1cb5857c48fa7757295482bd6a8ea1e Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 11:16:58 +1100 Subject: [PATCH 350/719] Get rid of Server class, serve in main --- qcodes/monitor/monitor.py | 64 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index faf4d3208de..bfb96eed8d9 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -6,8 +6,19 @@ # # Distributed under terms of the MIT license. """ -Monitor a set of parameter in a background thread -stream opuput over websocket +Monitor a set of parameters in a background thread +stream output over websocket + +To start monitor, run this file, or if qcodes is installed as a module: +``` +% python -m qcodes.monitor.monitor +``` + +Add parameters to monitor in your measurement by creating a new monitor with a list +of parameters to monitor: +``` +monitor = qcodes.Monitor(param1, param2, param3, ...) +``` """ import logging @@ -40,7 +51,7 @@ def _get_metadata(*parameters) -> Dict[str, Any]: Return a dict that contains the parameter metadata grouped by the instrument it belongs to. """ - ts = time.time() + metadata_timestamp = time.time() # group metadata by instrument metas = defaultdict(list) # type: dict for parameter in parameters: @@ -67,7 +78,7 @@ def _get_metadata(*parameters) -> Dict[str, Any]: temp = {"instrument": instrument, "parameters": metas[instrument]} parameters_out.append(temp) - state = {"ts": ts, "parameters": parameters_out} + state = {"ts": metadata_timestamp, "parameters": parameters_out} return state @@ -75,7 +86,7 @@ def _handler(parameters, interval: int): """ Return the websockets server handler """ - async def server_func(websocket, path): + async def server_func(websocket, _): """ Create a websockets handler that sends parameter values to a listener every "interval" seconds @@ -85,8 +96,8 @@ async def server_func(websocket, path): # Update the parameter values try: meta = _get_metadata(*parameters) - except ValueError as e: - log.exception(e) + except ValueError: + log.exception("Error getting parameters") break log.debug("sending.. to %r", websocket) await websocket.send(json.dumps(meta)) @@ -169,10 +180,10 @@ def update_all(self): """ Update all parameters in the monitor """ - for p in self._parameters: + for parameter in self._parameters: # call get if it can be called without arguments with suppress(TypeError): - p.get() + parameter.get() def stop(self) -> None: """ @@ -189,7 +200,7 @@ async def __stop_server(self): await self.loop.create_task(self.server.wait_closed()) log.debug("stopping loop") log.debug("Pending tasks at stop: %r", - asyncio.Task.all_tasks(self.loop)) + asyncio.Task.all_tasks(self.loop)) self.loop.stop() def join(self, timeout=None) -> None: @@ -232,28 +243,17 @@ def show(): """ webbrowser.open("http://localhost:{}".format(SERVER_PORT)) -class Server(): - - def __init__(self, port=SERVER_PORT): - self.port = port - self.handler = http.server.SimpleHTTPRequestHandler - self.httpd = socketserver.TCPServer(("", self.port), self.handler) - self.static_dir = os.path.join(os.path.dirname(__file__), 'dist') - - def run(self): - os.chdir(self.static_dir) - log.debug("serving directory %s", self.static_dir) - self.httpd.serve_forever() - - def stop(self): - self.httpd.shutdown() - - if __name__ == "__main__": - server = Server() - print("Open browser at http://localhost:{}".format(server.port)) + # If this file is run, create a simple webserver that serves a simple website + # that can be used to view monitored parameters. + STATIC_DIR = os.path.join(os.path.dirname(__file__), 'dist') + os.chdir(STATIC_DIR) try: - webbrowser.open("http://localhost:{}".format(server.port)) - server.run() + log.info("Starting HTTP Server at http://localhost:%i", SERVER_PORT) + with socketserver.TCPServer(("", SERVER_PORT), + http.server.SimpleHTTPRequestHandler) as httpd: + log.debug("serving directory %s", STATIC_DIR) + webbrowser.open("http://localhost:{}".format(SERVER_PORT)) + httpd.serve_forever() except KeyboardInterrupt: - exit() + log.info("Shutting Down HTTP Server") From 0d299c9b374ab35b2363deb5ba5b8ec5f7e17b27 Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 11:58:59 +1100 Subject: [PATCH 351/719] Resolution of windows time causes test to fail without equal check --- qcodes/tests/test_parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/test_parameter.py b/qcodes/tests/test_parameter.py index 4ed3c068708..f55791bd6ee 100644 --- a/qcodes/tests/test_parameter.py +++ b/qcodes/tests/test_parameter.py @@ -191,12 +191,12 @@ def test_get_latest(self): # Check we return last set value, with the correct timestamp self.assertEqual(local_parameter.get_latest(), 1) - self.assertTrue(before_set < local_parameter.get_latest.get_timestamp() < after_set) + self.assertTrue(before_set <= local_parameter.get_latest.get_timestamp() <= after_set) # Check that updating the value updates the timestamp local_parameter.set(2) self.assertEqual(local_parameter.get_latest(), 2) - self.assertGreater(local_parameter.get_latest.get_timestamp(), after_set) + self.assertGreaterEqual(local_parameter.get_latest.get_timestamp(), after_set) def test_has_set_get(self): # Create parameter that has no set_cmd, and get_cmd returns last value From 999c3eb3422df63d36e4fa410f5aa6b33f2c894d Mon Sep 17 00:00:00 2001 From: Sebastian Pauka Date: Wed, 5 Dec 2018 12:05:04 +1100 Subject: [PATCH 352/719] Add additional monitor tests for correct join behaviour --- qcodes/tests/test_monitor.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/qcodes/tests/test_monitor.py b/qcodes/tests/test_monitor.py index b1832d0969e..555db39f506 100644 --- a/qcodes/tests/test_monitor.py +++ b/qcodes/tests/test_monitor.py @@ -32,6 +32,29 @@ def test_setup_teardown(self): self.assertFalse(m.is_alive()) self.assertIsNone(monitor.Monitor.running) + def test_monitor_replace(self): + """ + Check that monitors get correctly replaced + """ + m = monitor.Monitor() + self.assertEqual(monitor.Monitor.running, m) + m2 = monitor.Monitor() + self.assertEqual(monitor.Monitor.running, m2) + self.assertTrue(m.loop.is_closed()) + self.assertFalse(m.is_alive()) + self.assertTrue(m2.is_alive()) + m2.stop() + + def test_double_join(self): + """ + Check that a double join doesn't cause a hang + """ + m = monitor.Monitor() + self.assertEqual(monitor.Monitor.running, m) + m.stop() + m.stop() + + def test_connection(self): """ Test that we can connect to a monitor instance From 0cf77f897a6d1edcc416c27469f1c28ad59f573f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Tue, 4 Dec 2018 18:07:21 -0800 Subject: [PATCH 353/719] add acquire and release lock return type hints --- qcodes/instrument_drivers/tektronix/Keithley_s46.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 06ead1f73c6..77d4f59d337 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -45,7 +45,7 @@ def __init__(self, relay_name: str): self.relay_name = relay_name self._locked_by: int = None - def acquire(self, channel_number: int): + def acquire(self, channel_number: int) -> None: """ Request a lock acquisition """ @@ -57,7 +57,7 @@ def acquire(self, channel_number: int): else: self._locked_by = channel_number - def release(self, channel_number: int): + def release(self, channel_number: int) -> None: """ Release a lock. """ From 9c6a4410391c69fb387efb7d491156716aa6a7e9 Mon Sep 17 00:00:00 2001 From: nyxus Date: Wed, 5 Dec 2018 10:10:49 +0100 Subject: [PATCH 354/719] RTO1000: rework after comments, removed .format() and change trigger_mode val_mapping to vals --- .../rohde_schwarz/RTO1000.py | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py index 1112920028e..375784820ee 100644 --- a/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py +++ b/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py @@ -209,64 +209,64 @@ def __init__(self, parent: Instrument, name: str, meas_nr: int): ) self.add_parameter('enable', - label='Measurement {} enable'.format(meas_nr), - set_cmd='MEASurement{}:ENABle {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} enable', + set_cmd=f'MEASurement{meas_nr}:ENABle {{}}', vals=vals.Enum('ON', 'OFF'), docstring='Switches the mesurment on or off') self.add_parameter('source', - label='Measurement {} source'.format(meas_nr), - set_cmd='MEASurement{}:SOURce {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} source', + set_cmd=f'MEASurement{meas_nr}:SOURce {{}}', vals=self.sources, docstring='Set the source of a measurement if the ' \ 'measurement only needs one source') self.add_parameter('source_first', - label='Measurement {} first source'.format(meas_nr), - set_cmd='MEASurement{}:FSRC {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} first source', + set_cmd=f'MEASurement{meas_nr}:FSRC {{}}', vals=self.sources, docstring='Set the first source of a measurement if the ' \ 'measurement only needs mutliple sources') self.add_parameter('source_second', - label='Measurement {} second source'.format(meas_nr), - set_cmd='MEASurement{}:SSRC {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} second source', + set_cmd=f'MEASurement{meas_nr}:SSRC {{}}', vals=self.sources, docstring='Set the second source of a measurement if the ' \ 'measurement only needs mutliple sources') self.add_parameter('category', - label='Measurement {} category'.format(meas_nr), - set_cmd='MEASurement{}:CATegory {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} category', + set_cmd=f'MEASurement{meas_nr}:CATegory {{}}', vals=self.categories, docstring='Set the category of a measurement') self.add_parameter('main', - label='Measurement {} main'.format(meas_nr), - set_cmd='MEASurement{}:MAIN {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} main', + set_cmd=f'MEASurement{meas_nr}:MAIN {{}}', vals=self.meas_type, docstring='Set the main of a measurement') self.add_parameter('statistics_enable', - label='Measurement {} enable statistics'.format(meas_nr), - set_cmd='MEASurement{}:STATistics:ENABle {{}}'.format(meas_nr), + label=f'Measurement {meas_nr} enable statistics', + set_cmd=f'MEASurement{meas_nr}:STATistics:ENABle {{}}', vals=vals.Enum('ON', 'OFF'), docstring='Switches the mesurment on or off') self.add_parameter('clear', - label='Measurement {} clear statistics'.format(meas_nr), - set_cmd='MEASurement{}:CLEar'.format(meas_nr), + label=f'Measurement {meas_nr} clear statistics', + set_cmd=f'MEASurement{meas_nr}:CLEar', docstring='Clears/reset measurement') self.add_parameter('event_count', - label='Measurement {} number of events'.format(meas_nr), - get_cmd='MEASurement{}:RESult:EVTCount?'.format(meas_nr), + label=f'Measurement {meas_nr} number of events', + get_cmd=f'MEASurement{meas_nr}:RESult:EVTCount?', get_parser=int, docstring='Number of measurement results in the long-term measurement') self.add_parameter('result_avg', - label='Measurement {} averages'.format(meas_nr), - get_cmd='MEASurement{}:RESult:AVG?'.format(meas_nr), + label=f'Measurement {meas_nr} averages', + get_cmd=f'MEASurement{meas_nr}:RESult:AVG?', get_parser=float, docstring='Average of the long-term measurement results') @@ -512,9 +512,7 @@ def __init__(self, name: str, address: str, label='Trigger mode', set_cmd='TRIGger:MODE {}', get_cmd='TRIGger1:SOURce?', - val_mapping={'AUTO': 'AUTO', - 'NORMAL': 'NORMal', - 'FREERUN': 'FREerun'}, + vals=vals.Enum('AUTO', 'NORMAL', 'FREERUN'), docstring='Sets the trigger mode which determines the ' \ ' behaviour of the instrument if no trigger occurs.\n' \ 'Options: AUTO, NORMAL, FREERUN.', @@ -672,9 +670,9 @@ def __init__(self, name: str, address: str, chan = ScopeChannel(self, 'channel{}'.format(ch), ch) self.add_submodule('ch{}'.format(ch), chan) - for meas in range(1, self.num_meas+1): - measCh = ScopeMeasurement(self, 'measurement{}'.format(meas), meas) - self.add_submodule('meas{}'.format(meas), measCh) + for measId in range(1, self.num_meas+1): + measCh = ScopeMeasurement(self, f'measurement{measId}', measId) + self.add_submodule(f'meas{measId}', measCh) self.add_function('stop', call_cmd='STOP') self.add_function('reset', call_cmd='*RST') From ab7bff4a3bb8fc8e3d1a76558211f02371edb53f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 10:36:05 +0100 Subject: [PATCH 355/719] filter warning --- qcodes/tests/dataset/test_sqlite_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index e1521914dd4..bc45b99f6d1 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -190,6 +190,7 @@ def test_runs_table_columns(empty_temp_db): assert colnames == [] +@pytest.mark.filterwarnings("ignore:get_data") def test_get_data_no_columns(scalar_dataset): ds = scalar_dataset ref = mut.get_data(ds.conn, ds.table_name, []) From 88a1b89c5b7856bf80075f112d807c28d03bed2b Mon Sep 17 00:00:00 2001 From: Shawn Storm Date: Tue, 4 Dec 2018 22:23:14 +0100 Subject: [PATCH 356/719] Changed 3.5+ to 3.6+ --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index e5e6c7d08d6..f5230ad3568 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ To get a feeling of qcodes browse the Jupyter notebooks in `docs/examples `__ . -QCoDeS is compatible with Python 3.5+. It is primarily intended for use +QCoDeS is compatible with Python 3.6+. It is primarily intended for use from Jupyter notebooks, but can be used from traditional terminal-based shells and in stand-alone scripts as well. The features in `qcodes.utils.magic` are exclusively for Jupyter notebooks. From c8fac47e3a82afb027ebf0d2f65b39a35ced1c86 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 13:53:38 +0100 Subject: [PATCH 357/719] Remove old get_columns --- qcodes/dataset/sqlite_base.py | 133 +++++++++-------------- qcodes/tests/dataset/helper_functions.py | 0 qcodes/tests/dataset/test_sqlite_base.py | 33 +++--- 3 files changed, 69 insertions(+), 97 deletions(-) create mode 100644 qcodes/tests/dataset/helper_functions.py diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 8d1f9324534..36e26774394 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1223,31 +1223,68 @@ def get_data(conn: ConnectionPlus, def get_parameter_data(conn: ConnectionPlus, table_name: str, columns: List[str], - start: int = None, - end: int = None) -> Dict[str, np.ndarray]: + start: Optional[int]=None, + end: Optional[int]=None) -> \ + Dict[str, Dict[str, np.ndarray]]: """ - Get data from the columns of a table. - Allows to specfiy a range. + Get data for one or more parameters and its dependencies. The data + is returned as numpy arrays nested 2 layers of dicts. The keys or the + outermost are the requested parameters and the second level by the loaded + parameters. Args: conn: database connection table_name: name of the table columns: list of columns - start: start of range (1 indedex) - end: start of range (1 indedex) + start: start of range; if None, then starts from the top of the table + end: end of range; if None, then ends at the bottom of the table + """ + output = {} + if len(columns) == 0: + raise NotImplementedError("HERE we should look up all " + "dependent standalone parameters") - Returns: - the data requested + # get run_id + sql = """ + SELECT run_id FROM runs WHERE result_table_name = ? """ - # Benchmarking shows that transposing the data with python types is faster - # than transposing the data using np.array.transpose - # This method is going to form the entry point for a compiled version + c = atomic_transaction(conn, sql, table_name) + run_id = one(c, 'run_id') - res = get_data(conn, table_name, columns, start, end) - res_t = list(map(list, zip(*res))) - return {name: np.array(column_data) - for name, column_data - in zip(columns, res_t)} + for param in columns: + params = get_dependency_parameters(conn, param, run_id) + columns = [param.name for param in params] + types = [param.type for param in params] + + res = get_data(conn, table_name, columns, start=start, end=end) + + if 'array' in types and ('numeric' in types or 'text' in types): + # todo: Should we check that all the arrays are the same size? + first_array_element = types.index('array') + numeric_elms = [i for i, x in enumerate(types) + if x == "numeric"] + text_elms = [i for i, x in enumerate(types) + if x == "text"] + for row in res: + for element in numeric_elms: + row[element] = np.full_like(row[first_array_element], + row[element], + dtype=np.float) + # todo should we handle int/float types here + for element in text_elms: + strlen = len(row[element]) + row[element] = np.full_like(row[first_array_element], + row[element], + dtype=f'U{strlen}') + + # Benchmarking shows that transposing the data with python types is faster + # than transposing the data using np.array.transpose + # This method is going to form the entry point for a compiled version + res_t = list(map(list, zip(*res))) + output[param] = {name: np.squeeze(np.array(column_data)) + for name, column_data + in zip(columns, res_t)} + return output def get_values(conn: ConnectionPlus, @@ -1520,70 +1557,6 @@ def get_dependency_parameters(conn: ConnectionPlus, param: str, return parameters -def get_data_of_param_and_deps_as_columns(conn: ConnectionPlus, - table_name: str, - columns: List[str], - start: Optional[int]=None, - end: Optional[int]=None) -> \ - Dict[str, Dict[str, np.ndarray]]: - """ - Get data for one or more parameters and its dependencies. The data - is returned as numpy arrays nested 2 layers of dicts. The keys or the - outermost are the requested parameters and the second level by the loaded - parameters. - - Args: - conn: database connection - table_name: name of the table - columns: list of columns - start: start of range; if None, then starts from the top of the table - end: end of range; if None, then ends at the bottom of the table - """ - output = {} - if len(columns) == 0: - raise NotImplementedError("HERE we should look up all " - "dependent standalone parameters") - - # get run_id - sql = """ - SELECT run_id FROM runs WHERE result_table_name = ? - """ - c = atomic_transaction(conn, sql, table_name) - run_id = one(c, 'run_id') - - for param in columns: - params = get_dependency_parameters(conn, param, run_id) - columns = [param.name for param in params] - types = [param.type for param in params] - - res = get_data(conn, table_name, columns, start=start, end=end) - - if 'array' in types and ('numeric' in types or 'text' in types): - # todo: Should we check that all the arrays are the same size? - first_array_element = types.index('array') - numeric_elms = [i for i, x in enumerate(types) - if x == "numeric"] - text_elms = [i for i, x in enumerate(types) - if x == "text"] - for row in res: - for element in numeric_elms: - row[element] = np.full_like(row[first_array_element], - row[element], - dtype=np.float) - # todo should we handle int/float types here - for element in text_elms: - strlen = len(row[element]) - row[element] = np.full_like(row[first_array_element], - row[element], - dtype=f'U{strlen}') - - res_t = list(map(list, zip(*res))) - output[param] = {name: np.squeeze(np.array(column_data)) - for name, column_data - in zip(columns, res_t)} - return output - - def new_experiment(conn: ConnectionPlus, name: str, sample_name: str, diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 94f9164d924..0d00e7f7798 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -26,6 +26,8 @@ error_caused_by # pylint: enable=unused-import +from .helper_functions import verify_data_dict + _unicode_categories = ('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nd', 'Pc', 'Pd', 'Zs') @@ -197,25 +199,22 @@ def test_get_data_no_columns(scalar_dataset): ref = mut.get_data(ds.conn, ds.table_name, []) assert ref == [[]] + def test_get_parameter_data(scalar_dataset): ds = scalar_dataset - params = ds.parameters.split(',') - # delete some random parameter to test it with an incomplete list - del params[-2] - - ref = mut.get_data(ds.conn, ds.table_name, params) - dut = mut.get_parameter_data(ds.conn, ds.table_name, params) - for i_row, row in enumerate(ref): - for i_param, param_name in enumerate(params): - v_ref = row[i_param] - v_test = dut[param_name][i_row] - if isinstance(v_ref, float): - assert isinstance(v_test, np.float64) - elif isinstance(v_ref, int): - assert isinstance(v_test, np.int) - else: - raise RuntimeError('Unsupported data type') - assert np.isclose(v_test, v_ref) + input_names = ['param_3'] + + data = mut.get_parameter_data(ds.conn, ds.table_name, input_names) + + assert len(data.keys()) == len(input_names) + + expected_names = {} + expected_names['param_3'] = ['param_0', 'param_1', 'param_2', + 'param_3'] + expected_shapes = {} + expected_shapes['param_3'] = [(10**3, )]*4 + + verify_data_dict(data, input_names, expected_names, expected_shapes) def test_is_run_id_in_db(empty_temp_db): conn = mut.connect(get_DB_location()) From 8bb57c8cf81a6da3cf986717a06fdd307f5f6050 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 13:54:22 +0100 Subject: [PATCH 358/719] remove method from dataset --- qcodes/dataset/data_set.py | 19 ++------ qcodes/tests/dataset/test_dataset_basic.py | 55 ++++++++-------------- 2 files changed, 22 insertions(+), 52 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 1d05c8513d8..20e081a812d 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -38,8 +38,7 @@ update_run_description, run_exists, remove_trigger, make_connection_plus_from, - ConnectionPlus, - get_data_of_param_and_deps_as_columns) + ConnectionPlus) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -809,7 +808,7 @@ def get_parameter_data( self, *params: Union[str, ParamSpec, _BaseParameter], start: Optional[int] = None, - end: Optional[int] = None) -> Dict[str, numpy.ndarray]: + end: Optional[int] = None) -> Dict[str, Dict[str, numpy.ndarray]]: """ Returns the values stored in the DataSet for the specified parameters. The values are returned as a dictionary of numpy arrays where the key, @@ -835,19 +834,7 @@ def get_parameter_data( """ valid_param_names = self._validate_parameters(*params) return get_parameter_data(self.conn, self.table_name, valid_param_names, - start, end) - - def get_data_of_param_and_deps_as_columns( - self, - *params: Union[str, ParamSpec, _BaseParameter], - start: Optional[int] = None, - end: Optional[int] = None) -> Dict[str, Dict[str, numpy.ndarray]]: - valid_param_names = self._validate_parameters(*params) - return get_data_of_param_and_deps_as_columns(self.conn, - self.table_name, - valid_param_names, - start, end) - + start, end) def get_values(self, param_name: str) -> List[List[Any]]: """ diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 7ed2950cce3..74460a7665f 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1,7 +1,6 @@ import itertools from copy import copy import re -from typing import Sequence, Tuple import pytest import numpy as np @@ -28,6 +27,8 @@ # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs +from .helper_functions import verify_data_dict + n_experiments = 0 @@ -774,18 +775,25 @@ def test_get_data_with_start_and_end_args(self, ds_with_vals, def test_get_parameter_data(scalar_dataset): - parameter_test_helper(scalar_dataset) + ds = scalar_dataset + input_names = ['param_3'] + data = ds.get_parameter_data(*input_names) -def test_get_array_parameter_data(array_dataset): - paramspecs = array_dataset.paramspecs - types = [param.type for param in paramspecs.values()] + assert len(data.keys()) == len(input_names) + + expected_names = {} + expected_names['param_3'] = ['param_0', 'param_1', 'param_2', + 'param_3'] + expected_shapes = {} + expected_shapes['param_3'] = [(10**3, )]*4 - if 'array' not in types: - parameter_test_helper(array_dataset) + verify_data_dict(data, input_names, expected_names, expected_shapes) + +def test_get_array_parameter_data(array_dataset): inputnames = ['testparameter'] - data = array_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + data = array_dataset.get_parameter_data(*inputnames) assert len(data.keys()) == len(inputnames) expected_names = {} expected_names['testparameter'] = ['testparameter', 'this_setpoint'] @@ -799,11 +807,8 @@ def test_get_multi_parameter_data(multi_dataset): paramspecs = multi_dataset.paramspecs types = [param.type for param in paramspecs.values()] - if 'array' not in types: - parameter_test_helper(multi_dataset) - inputnames = ['this', 'that'] - data = multi_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + data = multi_dataset.get_parameter_data(*inputnames) assert len(data.keys()) == len(inputnames) expected_names = {} expected_names['this'] = ['this', 'this_setpoint', 'that_setpoint'] @@ -822,11 +827,8 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset): paramspecs = array_in_scalar_dataset.paramspecs types = [param.type for param in paramspecs.values()] - if 'array' not in types: - parameter_test_helper(array_in_scalar_dataset) - inputnames = ['testparameter'] - data = array_in_scalar_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + data = array_in_scalar_dataset.get_parameter_data(*inputnames) assert len(data.keys()) == len(inputnames) expected_names = {} expected_names['testparameter'] = ['testparameter', 'scalarparam', @@ -843,11 +845,8 @@ def test_get_array_in_str_param_data(array_in_str_dataset): paramspecs = array_in_str_dataset.paramspecs types = [param.type for param in paramspecs.values()] - if 'array' not in types: - parameter_test_helper(array_in_str_dataset) - inputnames = ['testparameter'] - data = array_in_str_dataset.get_data_of_param_and_deps_as_columns(*inputnames) + data = array_in_str_dataset.get_parameter_data(*inputnames) assert len(data.keys()) == len(inputnames) expected_names = {} expected_names['testparameter'] = ['testparameter', 'textparam', @@ -895,19 +894,3 @@ def parameter_test_helper(ds): elif isinstance(v_ref, str): assert isinstance(v_test, np.str_) assert v_ref == v_test - - -def verify_data_dict(data, parameter_names, expected_names, - expected_shapes): - for param in parameter_names: - innerdata = data[param] - verify_data_dict_for_single_param(innerdata, - expected_names[param], - expected_shapes[param]) - - -def verify_data_dict_for_single_param(datadict, - names: Sequence[str], - shapes: Sequence[Tuple[int, ...]]): - for name, shape in zip(names, shapes): - assert datadict[name].shape == shape From 60b2eca8184013588e3f34f38d9aa8df1fe54cac Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 13:56:58 +0100 Subject: [PATCH 359/719] Update docstring --- qcodes/dataset/data_set.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 20e081a812d..f91ed7e9ebb 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -813,7 +813,10 @@ def get_parameter_data( Returns the values stored in the DataSet for the specified parameters. The values are returned as a dictionary of numpy arrays where the key, is given by the respective parameter name and the value arrays represent - the data points. This method returns the transpose of `get_data`. + the data points. If some of the parameters are stored as + arrays the remaining parameters are expanded to the same shape as these. + Apart from this expansion this method returns the transpose of + `get_data`. If provided, the start and end arguments select a range of results by result count (index). If the range is empty - that is, if the end is @@ -829,8 +832,8 @@ def get_parameter_data( None Returns: - Dictionary of numpy arrays containing the data points of type - numeric, array or string. + Dictionary from requested parameters to Dict of numpy arrays + containing the data points of type numeric, array or string. """ valid_param_names = self._validate_parameters(*params) return get_parameter_data(self.conn, self.table_name, valid_param_names, From 653fbb3b8051029d7390853d6494a67e9ccfbcf8 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 13:59:13 +0100 Subject: [PATCH 360/719] Add missing file --- qcodes/tests/dataset/helper_functions.py | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index e69de29bb2d..87b68c1c4a2 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -0,0 +1,33 @@ +from typing import Sequence, Tuple, Dict + +import numpy as np + + +def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], + parameter_names: Sequence[str], + expected_names: Dict[str, Sequence[str]], + expected_shapes: Dict[str, Sequence[Tuple[int, ...]]]) -> None: + """ + Simple helper function to verify a dict of data + + Args: + data: The data to verify + parameter_names: names of the parameters requested + expected_names: names of the paramerters expected to be loaded + expected_shapes: shapes of the paramters loaded + + Returns: + + """ + for param in parameter_names: + innerdata = data[param] + verify_data_dict_for_single_param(innerdata, + expected_names[param], + expected_shapes[param]) + + +def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], + names: Sequence[str], + shapes: Sequence[Tuple[int, ...]]): + for name, shape in zip(names, shapes): + assert datadict[name].shape == shape From d5cb99266460d501ce0a8dea0d0d6ede927d941c Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 14:00:19 +0100 Subject: [PATCH 361/719] typo --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 36e26774394..a6d690f840b 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1210,7 +1210,7 @@ def get_data(conn: ConnectionPlus, if len(columns) == 0: warnings.warn( 'get_data: requested data without specifying parameters/columns.' - 'Returning empyt list.' + 'Returning empty list.' ) return [[]] query = _build_data_query(table_name, columns, start, end) From c86579addf956d2ef55769c207095193ac5a3fb6 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 16:18:34 +0100 Subject: [PATCH 362/719] add function to get all non dependent parameters --- qcodes/dataset/sqlite_base.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index a6d690f840b..1f1f3279e00 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1524,13 +1524,34 @@ def get_dependencies(conn: ConnectionPlus, return res -def get_independent_parameters(conn: ConnectionPlus, - run_id: int): - """" - This should return all parameters that are neither - dependent on other parameters or dependencies of other parameters +def get_non_dependencies(conn: ConnectionPlus, + run_id: int) -> List[str]: """ - raise NotADirectoryError("TODO") + Return all parameters for a given run that are not dependencies of + other parameters. + + Args: + conn: connection to the database + run_id: The run_id of the run in question + + Returns: + + """ + parameters = get_parameters(conn, run_id) + maybe_independent = [] + dependent = [] + dependencies = [] + + for param in parameters: + if len(param.depends_on) == 0: + maybe_independent.append(param.name) + else: + dependent.append(param.name) + dependencies.extend(param.depends_on) + + independent = set(maybe_independent) - set(dependencies) + return sorted(list(independent)) + # Higher level Wrappers From 999bd2824eacc82bb6ef0b47953839f89f20d781 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 16:18:57 +0100 Subject: [PATCH 363/719] Cleanup logic and use new function --- qcodes/dataset/sqlite_base.py | 39 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 1f1f3279e00..6fdb790da49 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1239,25 +1239,26 @@ def get_parameter_data(conn: ConnectionPlus, start: start of range; if None, then starts from the top of the table end: end of range; if None, then ends at the bottom of the table """ - output = {} - if len(columns) == 0: - raise NotImplementedError("HERE we should look up all " - "dependent standalone parameters") - - # get run_id sql = """ SELECT run_id FROM runs WHERE result_table_name = ? """ c = atomic_transaction(conn, sql, table_name) run_id = one(c, 'run_id') - for param in columns: - params = get_dependency_parameters(conn, param, run_id) - columns = [param.name for param in params] - types = [param.type for param in params] - - res = get_data(conn, table_name, columns, start=start, end=end) - + output = {} + if len(columns) == 0: + columns = get_non_dependencies(conn, run_id) + + # loop over all the requested parameters + for output_param in columns: + # find all the dependencies of this param + paramspecs = get_parameter_dependencies(conn, output_param, run_id) + param_names = [param.name for param in paramspecs] + types = [param.type for param in paramspecs] + + res = get_data(conn, table_name, param_names, start=start, end=end) + # if we have array type parameters expand all other parameters + # to arrays if 'array' in types and ('numeric' in types or 'text' in types): # todo: Should we check that all the arrays are the same size? first_array_element = types.index('array') @@ -1277,13 +1278,13 @@ def get_parameter_data(conn: ConnectionPlus, row[element], dtype=f'U{strlen}') - # Benchmarking shows that transposing the data with python types is faster - # than transposing the data using np.array.transpose + # Benchmarking shows that transposing the data with python types is + # faster than transposing the data using np.array.transpose # This method is going to form the entry point for a compiled version res_t = list(map(list, zip(*res))) - output[param] = {name: np.squeeze(np.array(column_data)) + output[output_param] = {name: np.squeeze(np.array(column_data)) for name, column_data - in zip(columns, res_t)} + in zip(param_names, res_t)} return output @@ -1556,10 +1557,10 @@ def get_non_dependencies(conn: ConnectionPlus, # Higher level Wrappers -def get_dependency_parameters(conn: ConnectionPlus, param: str, +def get_parameter_dependencies(conn: ConnectionPlus, param: str, run_id: int) -> List[ParamSpec]: """ - Given a parameter name return its ParamSpec of the parameter along with + Given a parameter name return the ParamSpec of the parameter along with the ParamSpecs of all it's dependencies. Args: From 950f752dd2bd88c0167edaa335e20d1f7aea63d7 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 16:22:04 +0100 Subject: [PATCH 364/719] better tests --- qcodes/tests/dataset/dataset_fixtures.py | 22 ++++++++++++++++++++++ qcodes/tests/dataset/test_sqlite_base.py | 11 ++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index dd6729244c6..8f49ef5d820 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -104,3 +104,25 @@ def array_in_str_dataset(experiment, request): yield datasaver.dataset finally: datasaver.dataset.conn.close() + +@pytest.fixture +def standalone_parameters_dataset(dataset): + n_params = 3 + n_rows = 10**3 + params_indep = [ParamSpec(f'param_{i}', + 'numeric', + label=f'param_{i}', + unit='V') + for i in range(n_params)] + + params = params_indep + [ParamSpec(f'param_{n_params}', + 'numeric', + label=f'param_{n_params}', + unit='Ohm', + depends_on=params_indep[0:1])] + for p in params: + dataset.add_parameter(p) + dataset.add_results([{p.name: np.random.rand(1)[0] for p in params} + for _ in range(n_rows)]) + dataset.mark_complete() + yield dataset diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 0d00e7f7798..708bef3cb3e 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -21,7 +21,8 @@ # pylint: disable=unused-import from qcodes.tests.dataset.temporary_databases import \ empty_temp_db, experiment, dataset -from qcodes.tests.dataset.dataset_fixtures import scalar_dataset +from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, \ + standalone_parameters_dataset from qcodes.tests.dataset.test_database_creation_and_upgrading import \ error_caused_by # pylint: enable=unused-import @@ -216,6 +217,14 @@ def test_get_parameter_data(scalar_dataset): verify_data_dict(data, input_names, expected_names, expected_shapes) + +def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): + ds = standalone_parameters_dataset + params = mut.get_non_dependencies(ds.conn, + ds.run_id) + assert params == ['param_0', 'param_1', 'param_2'] + + def test_is_run_id_in_db(empty_temp_db): conn = mut.connect(get_DB_location()) mut.new_experiment(conn, 'test_exp', 'no_sample') From 25c9b9d0f936ae92682dad337e30fd5078eeea5e Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:07:22 +0100 Subject: [PATCH 365/719] look up parameters if missing --- qcodes/dataset/data_set.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index f91ed7e9ebb..5f108e0b39f 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -38,7 +38,8 @@ update_run_description, run_exists, remove_trigger, make_connection_plus_from, - ConnectionPlus) + ConnectionPlus, + get_non_dependencies) from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies @@ -835,7 +836,11 @@ def get_parameter_data( Dictionary from requested parameters to Dict of numpy arrays containing the data points of type numeric, array or string. """ - valid_param_names = self._validate_parameters(*params) + if len(params) == 0: + valid_param_names = get_non_dependencies(self.conn, + self.run_id) + else: + valid_param_names = self._validate_parameters(*params) return get_parameter_data(self.conn, self.table_name, valid_param_names, start, end) From 21c57d6e1bef06295a44db05a2525b8991dccbbd Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:08:41 +0100 Subject: [PATCH 366/719] add tests for dataset interface --- qcodes/tests/dataset/test_dataset_basic.py | 30 ++++++++++++++++++++-- qcodes/tests/dataset/test_sqlite_base.py | 20 ++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 74460a7665f..9d97c57ee07 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -15,7 +15,7 @@ from qcodes.tests.dataset.test_database_creation_and_upgrading import \ error_caused_by from qcodes.tests.dataset.test_descriptions import some_paramspecs -from qcodes.dataset.sqlite_base import _unicode_categories +from qcodes.dataset.sqlite_base import _unicode_categories, get_non_dependencies from qcodes.dataset.database import get_DB_location from qcodes.dataset.data_set import CompletedError, DataSet from qcodes.dataset.guids import parse_guid @@ -23,7 +23,8 @@ from qcodes.tests.dataset.temporary_databases import (empty_temp_db, experiment, dataset) from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, \ - array_dataset, multi_dataset, array_in_scalar_dataset, array_in_str_dataset + array_dataset, multi_dataset, array_in_scalar_dataset, array_in_str_dataset, \ + standalone_parameters_dataset # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -859,6 +860,31 @@ def test_get_array_in_str_param_data(array_in_str_dataset): verify_data_dict(data, inputnames, expected_names, expected_shapes) +def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): + ds = standalone_parameters_dataset + params = get_non_dependencies(ds.conn, + ds.run_id) + expected_toplevel_params = ['param_1', 'param_2', 'param_3'] + assert params == expected_toplevel_params + + data = standalone_parameters_dataset.get_parameter_data() + + assert len(data.keys()) == len(expected_toplevel_params) + + expected_names = {} + expected_names['param_1'] = [] + expected_names['param_2'] = [] + expected_names['param_3'] = ['param_0'] + + expected_shapes = {} + expected_shapes['param_1'] = [(10 ** 3,)] + expected_shapes['param_2'] = [(10 ** 3,)] + expected_shapes['param_3'] = [(10**3, )]*2 + + verify_data_dict(data, expected_toplevel_params, expected_names, + expected_shapes) + + def parameter_test_helper(ds): params = ds.parameters.split(',') # delete some random parameter to test it with an incomplete list diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 708bef3cb3e..fc408c7ef51 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -222,7 +222,25 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset ds = standalone_parameters_dataset params = mut.get_non_dependencies(ds.conn, ds.run_id) - assert params == ['param_0', 'param_1', 'param_2'] + expected_toplevel_params = ['param_1', 'param_2', 'param_3'] + assert params == expected_toplevel_params + + data = mut.get_parameter_data(ds.conn, ds.table_name) + + assert len(data.keys()) == len(expected_toplevel_params) + + expected_names = {} + expected_names['param_1'] = [] + expected_names['param_2'] = [] + expected_names['param_3'] = ['param_0'] + + expected_shapes = {} + expected_shapes['param_1'] = [(10 ** 3,)] + expected_shapes['param_2'] = [(10 ** 3,)] + expected_shapes['param_3'] = [(10**3, )]*2 + + verify_data_dict(data, expected_toplevel_params, expected_names, + expected_shapes) def test_is_run_id_in_db(empty_temp_db): From 9a39480dd47f8715938540e903b82c35aef1d35f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:09:16 +0100 Subject: [PATCH 367/719] include dependent in output and correct a bug --- qcodes/dataset/sqlite_base.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 6fdb790da49..e3976ac3c4a 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1222,7 +1222,7 @@ def get_data(conn: ConnectionPlus, def get_parameter_data(conn: ConnectionPlus, table_name: str, - columns: List[str], + columns: Sequence[str]=(), start: Optional[int]=None, end: Optional[int]=None) -> \ Dict[str, Dict[str, np.ndarray]]: @@ -1548,10 +1548,12 @@ def get_non_dependencies(conn: ConnectionPlus, maybe_independent.append(param.name) else: dependent.append(param.name) - dependencies.extend(param.depends_on) + dependencies.extend(param.depends_on.split(',')) independent = set(maybe_independent) - set(dependencies) - return sorted(list(independent)) + dependent = set(dependent) + result = independent.union(dependent) + return sorted(list(result)) # Higher level Wrappers From 1b382400591ba22e6aa2d9b118f42516692d51d9 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:15:31 +0100 Subject: [PATCH 368/719] clarify docstring --- qcodes/dataset/data_set.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 5f108e0b39f..0d3e6704e5d 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -826,7 +826,9 @@ def get_parameter_data( Args: *params: string parameter names, QCoDeS Parameter objects, and - ParamSpec objects + ParamSpec objects. If no parameters are supplied data for + all parameters that are not a dependency of another + parameter will be returned. start: start value of selection range (by result count); ignored if None end: end value of selection range (by results count); ignored if From 7347f7dfa5620c6fe1b5ce3f13f73dbcf222d07f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:24:16 +0100 Subject: [PATCH 369/719] more docstring work --- qcodes/dataset/data_set.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 0d3e6704e5d..b788ba51b12 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -811,13 +811,17 @@ def get_parameter_data( start: Optional[int] = None, end: Optional[int] = None) -> Dict[str, Dict[str, numpy.ndarray]]: """ - Returns the values stored in the DataSet for the specified parameters. - The values are returned as a dictionary of numpy arrays where the key, - is given by the respective parameter name and the value arrays represent - the data points. If some of the parameters are stored as + Returns the values stored in the DataSet for the specified parameters + and their dependencies. If no paramerers are supplied the values will + be returned for all parameters that are not them self depdendencies. + + The values are returned as a dictionary with names of the requested + parameters as keys and values consisting of dictionaries with the + names of the parameters and its dependencies as keys and numpy arrays + of the data as values. If some of the parameters are stored as arrays the remaining parameters are expanded to the same shape as these. - Apart from this expansion this method returns the transpose of - `get_data`. + Apart from this expansion the data returned by this method + is the transpose of the date returned by `get_data`. If provided, the start and end arguments select a range of results by result count (index). If the range is empty - that is, if the end is @@ -835,8 +839,9 @@ def get_parameter_data( None Returns: - Dictionary from requested parameters to Dict of numpy arrays - containing the data points of type numeric, array or string. + Dictionary from requested parameters to Dict of parameter names + to numpy arrays containing the data points of type numeric, + array or string. """ if len(params) == 0: valid_param_names = get_non_dependencies(self.conn, From b2fc15447b1eb3b2fc44d087e3b1fc3d0be00426 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 17:44:36 +0100 Subject: [PATCH 370/719] Fix typeing issues --- qcodes/dataset/sqlite_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index e3976ac3c4a..a3564cefb60 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1541,7 +1541,7 @@ def get_non_dependencies(conn: ConnectionPlus, parameters = get_parameters(conn, run_id) maybe_independent = [] dependent = [] - dependencies = [] + dependencies: List[str] = [] for param in parameters: if len(param.depends_on) == 0: @@ -1550,9 +1550,9 @@ def get_non_dependencies(conn: ConnectionPlus, dependent.append(param.name) dependencies.extend(param.depends_on.split(',')) - independent = set(maybe_independent) - set(dependencies) - dependent = set(dependent) - result = independent.union(dependent) + independent_set = set(maybe_independent) - set(dependencies) + dependent_set = set(dependent) + result = independent_set.union(dependent_set) return sorted(list(result)) From 03a67e65cf29a7666c551f208523f516eb7ac035 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 5 Dec 2018 20:48:35 +0100 Subject: [PATCH 371/719] Fix parsing of depends string --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index a3564cefb60..13425a74a05 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1548,7 +1548,7 @@ def get_non_dependencies(conn: ConnectionPlus, maybe_independent.append(param.name) else: dependent.append(param.name) - dependencies.extend(param.depends_on.split(',')) + dependencies.extend(param.depends_on.split(', ')) independent_set = set(maybe_independent) - set(dependencies) dependent_set = set(dependent) From 22e3e444f9c151b920caac366f146636e122cc5f Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 5 Dec 2018 19:02:12 -0800 Subject: [PATCH 372/719] 1) Instead of using InstrumentChannel, make individual parameters (e.g. A1, B2, etc) 2) Use the caching functions of the parameters instead of rolling your own 3) Use the visa logger in the test to verify that ":CLOS ?" is called only once. --- .../QCodes example with Keithley S46.ipynb | 130 ++++++++++----- .../tektronix/Keithley_s46.py | 157 +++++++----------- qcodes/tests/drivers/test_keithley_s46.py | 104 ++++++------ 3 files changed, 202 insertions(+), 189 deletions(-) diff --git a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb index 2e9132e83a4..f111489e1e9 100644 --- a/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb +++ b/docs/examples/driver_examples/QCodes example with Keithley S46.ipynb @@ -30,37 +30,57 @@ "cell_type": "code", "execution_count": 2, "metadata": {}, + "outputs": [], + "source": [ + "s46 = S46(\"s2\", \"GPIB0::7::INSTR\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connected to: KEITHLEY INSTRUMENTS INC. SYSTEM 46 (serial:1327388, firmware:A03) in 0.54s\n" + "['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'R5', 'R8']\n", + "26\n" ] } ], "source": [ - "s46 = S46(\"s2\", \"GPIB0::7::INSTR\")" + "print(s46.available_channels)\n", + "print(len(s46.available_channels))" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "26" + "['A2', 'B1']" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "len(s46.channels)" + "s46.closed_channels()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "s46.open_all_channels()" ] }, { @@ -80,22 +100,13 @@ } ], "source": [ - "s46.get_closed_channels()" + "s46.closed_channels()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, - "outputs": [], - "source": [ - "s46.A1.state(\"open\")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, "outputs": [ { "data": { @@ -103,27 +114,27 @@ "'open'" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.A1.state()" + "s46.A1()" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "s46.A1.state(\"close\")" + "s46.A1(\"close\")" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -132,51 +143,51 @@ "'close'" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.A1.state()" + "s46.A1()" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "['A1']" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.get_closed_channels()" + "s46.closed_channels()" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "('Relay A is already in use by channel 1', 'setting s2_A2_state to close')\n" + "Relay A is already in use by channel 1\n" ] } ], "source": [ "try: \n", - " s46.A2.state(\"close\")\n", + " s46.A2(\"close\")\n", " raise(\"We should not be here\")\n", "except LockAcquisitionError as e: \n", " print(e)" @@ -184,38 +195,38 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ - "s46.A1.state(\"open\")" + "s46.A1(\"open\")" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ - "s46.A2.state(\"close\")" + "s46.A2(\"close\")" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "('Relay A is already in use by channel 2', 'setting s2_A1_state to close')\n" + "Relay A is already in use by channel 2\n" ] } ], "source": [ "try: \n", - " s46.A1.state(\"close\")\n", + " s46.A1(\"close\")\n", " raise(\"We should not be here\")\n", "except LockAcquisitionError as e: \n", " print(e)" @@ -223,29 +234,29 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ - "s46.B1.state(\"close\")" + "s46.B1(\"close\")" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "('Relay B is already in use by channel 7', 'setting s2_B2_state to close')\n" + "Relay B is already in use by channel 7\n" ] } ], "source": [ "try: \n", - " s46.B2.state(\"close\")\n", + " s46.B2(\"close\")\n", " raise(\"We should not be here\")\n", "except LockAcquisitionError as e: \n", " print(e)" @@ -253,7 +264,27 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['A2', 'B1']" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s46.closed_channels()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -262,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -271,14 +302,21 @@ "[]" ] }, - "execution_count": 25, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "s46.get_closed_channels()" + "s46.closed_channels()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 77d4f59d337..3a91064ab08 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -3,34 +3,16 @@ """ import re from itertools import product +from functools import partial -from typing import Callable, Any, Union, Dict, List -from qcodes import Instrument, VisaInstrument, InstrumentChannel, ChannelList -from qcodes.utils.validators import Enum +from typing import Any, Dict, List, Optional +from qcodes import Instrument, VisaInstrument, Parameter class LockAcquisitionError(Exception): pass -def cached_method(method: Callable) -> Callable: - """ - A decorator which adds a keyword 'get_cached' to a method. When - 'get_cached=True', the decorated method returns a cached return value. If - the method has not been called before, or 'get_cached=False' the original - method is called. - """ - def inner(self, *args: Any, get_cached: bool=False, **kwargs: Any) -> Any: - if not hasattr(self, "__cached_values__"): - self.__cached_values__ = {} - - if method not in self.__cached_values__ or not get_cached: - self.__cached_values__[method] = method(self, *args, **kwargs) - - return self.__cached_values__[method] - return inner - - class RelayLock: """ The S46 either has six pole or a four pole relays. For example, channels @@ -65,36 +47,35 @@ def release(self, channel_number: int) -> None: self._locked_by = None -class S46Channel(InstrumentChannel): +class S46Parameter(Parameter): """ - A channel class for the S46 + A parameter class for S46 channels. We do not use the QCoDeS + InstrumentChannel class because our channel has one state parameter, + which can either be "open" or "close". Args: - parent name - channel_number: unlike other instruments, channel numbers on the - S46 will not be contiguous. That is, we may have channels 1, 2 and 4 - but channel 3 may be missing. - relay_lock: When closing the channel, request a lock acquisition. - Release the lock when opening + instrument + channel_number + lock: Acquire the lock when closing and release when opening """ def __init__( self, - parent: Union[Instrument, 'InstrumentChannel'], name: str, + instrument: Optional[Instrument], channel_number: int, - relay_lock: RelayLock + lock: RelayLock ): - super().__init__(parent, name) + super().__init__(name, instrument) + self._lock = lock self._channel_number = channel_number - self._relay_lock = relay_lock - # Acquire the lock if upon init we find the channel closed. - if self._get_state(init=True) == "close": + self.get = partial(self._get, get_cached=False) + + if self._get(get_cached=True) == "close": try: - self._relay_lock.acquire(self._channel_number) + self._lock.acquire(self._channel_number) except LockAcquisitionError as e: - # another channel has already acquired the lock raise RuntimeError( "The driver is initialized from an undesirable instrument " "state where more then one channel on a single relay is " @@ -102,36 +83,25 @@ def __init__( "Refusing to initialize driver!" ) from e - self.add_parameter( - "state", - get_cmd=self._get_state, - set_cmd=self._set_state, - vals=Enum("open", "close") - ) + self.set = self._set - def _get_state(self, init: bool=False) -> str: - """ - Args: - init: When calling this method from self.__init__, make this - value 'True'. This will prevent the instrument being queried - ':CLOS?' for each channel. - """ - closed_channels = self.parent.get_closed_channel_numbers( - get_cached=init) + def _get(self, get_cached): - is_closed = self._channel_number in closed_channels - return {True: "close", False: "open"}[is_closed] + closed_channels = self._instrument.closed_channels.get_latest() + + if not get_cached or closed_channels is None: + closed_channels = self._instrument.closed_channels.get() + + return "close" if self.name in closed_channels else "open" + + def _set(self, new_state) -> None: - def _set_state(self, new_state: str) -> None: - """ - Open/Close the channel - """ if new_state == "close": - self._relay_lock.acquire(self._channel_number) + self._lock.acquire(self._channel_number) elif new_state == "open": - self._relay_lock.release(self._channel_number) + self._lock.release(self._channel_number) - self.write(f":{new_state} (@{self._channel_number})") + self._instrument.write(f":{new_state} (@{self._channel_number})") @property def channel_number(self) -> int: @@ -144,13 +114,15 @@ class S46(VisaInstrument): # Make a dictionary where keys are channel aliases (e.g. 'A1', 'B3', etc) # and values are corresponding channel numbers. - aliases: Dict[str, int] = { + channel_numbers: Dict[str, int] = { f"{a}{b}": count + 1 for count, (a, b) in enumerate(product( ["A", "B", "C", "D"], range(1, 7) )) } - aliases.update({f"R{i}": i + 24 for i in range(1, 9)}) + channel_numbers.update({f"R{i}": i + 24 for i in range(1, 9)}) + # Make a reverse dict for efficient alias lookup given a channel number + aliases = dict((v, k) for k, v in channel_numbers.items()) def __init__( self, @@ -161,13 +133,14 @@ def __init__( super().__init__(name, address, terminator="\n", **kwargs) - channels = ChannelList( - self, - "channel", - S46Channel, - snapshotable=False + self.add_parameter( + "closed_channels", + get_cmd=":CLOS?", + get_parser=self._get_closed_channels_parser ) + self._available_channels: List[str] = [] + for relay_name, channel_count in zip( S46.relay_names, self.relay_layout): @@ -181,40 +154,28 @@ def __init__( alias = relay_name # For channels R1 to R8, we have one # channel per relay. Channel alias = relay name - channel_number = S46.aliases[alias] - channel = S46Channel(self, alias, channel_number, relay_lock) - channels.append(channel) - self.add_submodule(alias, channel) + self.add_parameter( + alias, + channel_number=S46.channel_numbers[alias], + lock=relay_lock, + parameter_class=S46Parameter + ) - self.add_submodule("channels", channels) - self.connect_message() + self._available_channels.append(alias) - @cached_method - def get_closed_channel_numbers(self) -> List[int]: + @staticmethod + def _get_closed_channels_parser(reply: str) -> List[str]: """ - Query the instrument for closed channels. Add an option to return - a cached response so we can prevent this method from being called - repeatedly for each channel during initialization of the driver. + The SCPI command ":CLOS ?" returns a reply in the form + "(@1,9)", if channels 1 and 9 are closed. Return a list of + strings, representing the aliases of the closed channels """ - closed_channels_str = re.findall(r"\d+", self.ask(":CLOS?")) - return [int(i) for i in closed_channels_str] - - def get_closed_channels(self) -> List[S46Channel]: - """ - Return a list of closed channels as a list of channel objects - """ - return [ - channel for channel in self.channels if - channel.channel_number in self.get_closed_channel_numbers() - ] + closed_channels_str = re.findall(r"\d+", reply) + return [S46.aliases[int(i)] for i in closed_channels_str] def open_all_channels(self) -> None: - """ - Please do not write ':OPEN ALL' to the instrument as this will - circumvent the lock. - """ - for channel in self.get_closed_channels(): - channel.state("open") + for channel_name in self.closed_channels(): + self.parameters[channel_name].set("open") @property def relay_layout(self) -> List[int]: @@ -223,3 +184,7 @@ def relay_layout(self) -> List[int]: that we can have zero channels per relay. """ return [int(i) for i in self.ask(":CONF:CPOL?").split(",")] + + @property + def available_channels(self) -> List[str]: + return self._available_channels diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 5a38c5dc91e..c5417f1fe1b 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -1,8 +1,12 @@ +from io import StringIO +import logging + import pytest from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( S46, LockAcquisitionError ) +from qcodes.instrument.visa import VISA_LOGGER import qcodes.instrument.sims as sims visalib = sims.__file__.replace('__init__.py', 'Keithley_s46.yaml@sim') @@ -20,21 +24,9 @@ def calc_channel_nr(alias: str) -> int: offset_dict = dict(zip(["A", "B", "C", "D", "R"], range(0, 32, 6))) return offset_dict[alias[0]] + int(alias[1:]) - assert all([nr == calc_channel_nr(al) for al, nr in S46.aliases.items()]) - - -class S46LoggedAsk(S46): - """ - A version of the driver which logs every ask command. We need this to - assert that ':CLOS?' is called once during initialization - """ - def __init__(self, *args, **kwargs): - self._ask_log = [] - super().__init__(*args, **kwargs) - - def ask(self, cmd: str): - self._ask_log.append(cmd) - return super().ask(cmd) + assert all([ + nr == calc_channel_nr(al) for al, nr in S46.channel_numbers.items() + ]) @pytest.fixture(scope='module') @@ -42,7 +34,15 @@ def s46_six(): """ A six channel-per-relay instrument """ - driver = S46LoggedAsk('s46_six', address='GPIB::2::INSTR', visalib=visalib) + io_stream = StringIO() + handler = logging.StreamHandler(io_stream) + logger = logging.getLogger(VISA_LOGGER) + logger.setLevel(logging.DEBUG) + logger.addHandler(handler) + + driver = S46('s46_six', address='GPIB::2::INSTR', visalib=visalib) + driver.io_stream = io_stream + yield driver driver.close() @@ -52,7 +52,15 @@ def s46_four(): """ A four channel-per-relay instrument """ - driver = S46LoggedAsk('s46_four', address='GPIB::3::INSTR', visalib=visalib) + io_stream = StringIO() + handler = logging.StreamHandler(io_stream) + logger = logging.getLogger(VISA_LOGGER) + logger.setLevel(logging.DEBUG) + logger.addHandler(handler) + + driver = S46('s46_four', address='GPIB::3::INSTR', visalib=visalib) + driver.io_stream = io_stream + yield driver driver.close() @@ -74,36 +82,28 @@ def test_init_six(s46_six): """ Test that the six channel instrument initializes correctly. """ - assert s46_six._ask_log.count(":CLOS?") == 1 + log_messages = s46_six.io_stream.getvalue() + assert log_messages.count(":CLOS?") == 1 + assert len(s46_six.available_channels) == 26 - n_channels = len(s46_six.channels) - # Channels A1 to D6 + R5 + R8 (4 * 6 + 2) - assert n_channels == 26 - - closed_channels = [1, 8, 13] - - for channel in s46_six.channels: - channel_nr = S46.aliases[channel.short_name] - state = "close" if channel_nr in closed_channels else "open" - assert channel.state() == state + closed_channel_numbers = [1, 8, 13] + assert s46_six.closed_channels() == [ + S46.aliases[i] for i in closed_channel_numbers + ] def test_init_four(s46_four): """ Test that the six channel instrument initializes correctly. """ - assert s46_four._ask_log.count(":CLOS?") == 1 - - n_channels = len(s46_four.channels) - # Channels A1 to D4 + R5 + R8 (4 * 4 + 2) - assert n_channels == 18 + log_messages = s46_four.io_stream.getvalue() + assert log_messages.count(":CLOS?") == 1 + assert len(s46_four.available_channels) == 18 - closed_channels = [1, 8] - - for channel in s46_four.channels: - channel_nr = S46.aliases[channel.short_name] - state = "close" if channel_nr in closed_channels else "open" - assert channel.state() == state + closed_channel_numbers = [1, 8] + assert s46_four.closed_channels() == [ + S46.aliases[i] for i in closed_channel_numbers + ] # A four channel instrument will have channels missing for relay in ["A", "B", "C", "D"]: @@ -118,7 +118,7 @@ def test_channel_number_invariance(s46_four, s46_six): channel aliases should represent the same channel. See also page 2-5 of the manual (e.g. B1 is *always* channel 7) """ - for alias in S46.aliases.keys(): + for alias in S46.channel_numbers.keys(): if hasattr(s46_four, alias) and hasattr(s46_six, alias): channel_four = getattr(s46_four, alias) channel_six = getattr(s46_six, alias) @@ -136,21 +136,31 @@ def test_locking_mechanism(s46_six): match="is already in use by channel" ): # A1 should be closed already - s46_six.A2.state("close") + s46_six.A2("close") # release the lock - s46_six.A1.state("open") + s46_six.A1("open") # now we should be able to close A2 - s46_six.A2.state("close") + s46_six.A2("close") # Let C1 acquire the lock - s46_six.C1.state("close") + s46_six.C1("close") # closing C2 should raise an error with pytest.raises( LockAcquisitionError, match="is already in use by channel" ): - s46_six.C2.state("close") + s46_six.C2("close") # Upon opening C1 we should be able to close C2 - s46_six.C1.state("open") - s46_six.C2.state("close") + s46_six.C1("open") + s46_six.C2("close") + + +def test_open_all(s46_six): + """ + Verify that calling 'open_all_channels' does not cause an exception. + Unfortunately, pyvisa-sim is not flexible enough for us to test if channels + have truly opened. + """ + s46_six.open_all_channels() + From 9168549ce799e1f753ef927249bfabb9cdaa4f70 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 6 Dec 2018 12:49:42 +0100 Subject: [PATCH 373/719] Better tests --- qcodes/tests/dataset/test_dataset_basic.py | 112 +++++++++------------ 1 file changed, 46 insertions(+), 66 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 9d97c57ee07..240ee680440 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -779,38 +779,39 @@ def test_get_parameter_data(scalar_dataset): ds = scalar_dataset input_names = ['param_3'] - data = ds.get_parameter_data(*input_names) - - assert len(data.keys()) == len(input_names) - expected_names = {} expected_names['param_3'] = ['param_0', 'param_1', 'param_2', 'param_3'] expected_shapes = {} expected_shapes['param_3'] = [(10**3, )]*4 - verify_data_dict(data, input_names, expected_names, expected_shapes) + parameter_test_helper(scalar_dataset, + input_names, + expected_names, + expected_shapes) + def test_get_array_parameter_data(array_dataset): - inputnames = ['testparameter'] - data = array_dataset.get_parameter_data(*inputnames) - assert len(data.keys()) == len(inputnames) + input_names = ['testparameter'] + expected_names = {} expected_names['testparameter'] = ['testparameter', 'this_setpoint'] expected_shapes = {} expected_shapes['testparameter'] = [(5, ), (5, )] - verify_data_dict(data, inputnames, expected_names, expected_shapes) + parameter_test_helper(array_dataset, + input_names, + expected_names, + expected_shapes) def test_get_multi_parameter_data(multi_dataset): paramspecs = multi_dataset.paramspecs types = [param.type for param in paramspecs.values()] - inputnames = ['this', 'that'] - data = multi_dataset.get_parameter_data(*inputnames) - assert len(data.keys()) == len(inputnames) + input_names = ['this', 'that'] + expected_names = {} expected_names['this'] = ['this', 'this_setpoint', 'that_setpoint'] expected_names['that'] = ['that', 'this_setpoint', 'that_setpoint'] @@ -821,16 +822,18 @@ def test_get_multi_parameter_data(multi_dataset): else: expected_shapes['this'] = [(15,), (15,)] expected_shapes['that'] = [(15,), (15,)] - verify_data_dict(data, inputnames, expected_names, expected_shapes) + parameter_test_helper(multi_dataset, + input_names, + expected_names, + expected_shapes) def test_get_array_in_scalar_param_data(array_in_scalar_dataset): paramspecs = array_in_scalar_dataset.paramspecs types = [param.type for param in paramspecs.values()] - inputnames = ['testparameter'] - data = array_in_scalar_dataset.get_parameter_data(*inputnames) - assert len(data.keys()) == len(inputnames) + input_names = ['testparameter'] + expected_names = {} expected_names['testparameter'] = ['testparameter', 'scalarparam', 'this_setpoint'] @@ -839,16 +842,18 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset): expected_shapes['testparameter'] = [(9, 5), (9, 5)] else: expected_shapes['testparameter'] = [(45,), (45,)] - verify_data_dict(data, inputnames, expected_names, expected_shapes) + parameter_test_helper(array_in_scalar_dataset, + input_names, + expected_names, + expected_shapes) def test_get_array_in_str_param_data(array_in_str_dataset): paramspecs = array_in_str_dataset.paramspecs types = [param.type for param in paramspecs.values()] - inputnames = ['testparameter'] - data = array_in_str_dataset.get_parameter_data(*inputnames) - assert len(data.keys()) == len(inputnames) + input_names = ['testparameter'] + expected_names = {} expected_names['testparameter'] = ['testparameter', 'textparam', 'this_setpoint'] @@ -857,20 +862,19 @@ def test_get_array_in_str_param_data(array_in_str_dataset): expected_shapes['testparameter'] = [(3, 5), (3, 5)] else: expected_shapes['testparameter'] = [(15,), (15,)] - verify_data_dict(data, inputnames, expected_names, expected_shapes) + parameter_test_helper(array_in_str_dataset, + input_names, + expected_names, + expected_shapes) def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): ds = standalone_parameters_dataset - params = get_non_dependencies(ds.conn, - ds.run_id) + params = get_non_dependencies(ds.conn, ds.run_id) + expected_toplevel_params = ['param_1', 'param_2', 'param_3'] assert params == expected_toplevel_params - data = standalone_parameters_dataset.get_parameter_data() - - assert len(data.keys()) == len(expected_toplevel_params) - expected_names = {} expected_names['param_1'] = [] expected_names['param_2'] = [] @@ -881,42 +885,18 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset expected_shapes['param_2'] = [(10 ** 3,)] expected_shapes['param_3'] = [(10**3, )]*2 - verify_data_dict(data, expected_toplevel_params, expected_names, - expected_shapes) - - -def parameter_test_helper(ds): - params = ds.parameters.split(',') - # delete some random parameter to test it with an incomplete list - del params[-2] - # replace first list entry by paramspec - param_names = copy(params) - params[0] = ds.paramspecs[params[0]] - - - - ref = ds.get_data(*params) - dut = ds.get_parameter_data(*params) - - column_lengths = [] - for col in dut.values(): - column_lengths.append(col.size) - column_lengths = np.array(column_lengths) - assert np.all(column_lengths == column_lengths[0]) - - for i_row, row in enumerate(ref): - for i_param, param_name in enumerate(param_names): - v_ref = row[i_param] - v_test = dut[param_name][i_row] - if isinstance(v_ref, float): - assert isinstance(v_test, np.float64) - assert np.isclose(v_test, v_ref) - elif isinstance(v_ref, int): - # default datatype for int is c_long which is 32 bit on - # windows and 64bit on linux - assert isinstance(v_test, np.int32) or \ - isinstance(v_test, np.int64) - assert np.isclose(v_test, v_ref) - elif isinstance(v_ref, str): - assert isinstance(v_test, np.str_) - assert v_ref == v_test + parameter_test_helper(ds, + expected_toplevel_params, + expected_names, + expected_shapes) + + +def parameter_test_helper(ds, toplevel_names, expected_names, expected_shapes): + data = ds.get_parameter_data(*toplevel_names) + all_data = ds.get_parameter_data() + + assert data.keys() == all_data.keys() + assert len(data.keys()) == len(toplevel_names) + + verify_data_dict(data, toplevel_names, expected_names, expected_shapes) + verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes) From 2740aa05add0a212d90018ec349768f675aa07e5 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 6 Dec 2018 12:50:00 +0100 Subject: [PATCH 374/719] pep8 --- qcodes/tests/dataset/dataset_fixtures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index 8f49ef5d820..bd1a749f8f2 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -105,6 +105,7 @@ def array_in_str_dataset(experiment, request): finally: datasaver.dataset.conn.close() + @pytest.fixture def standalone_parameters_dataset(dataset): n_params = 3 From d78d662036bd882ffd23ff5d5ad221f2fa3fad7a Mon Sep 17 00:00:00 2001 From: sochatoo Date: Fri, 7 Dec 2018 08:24:25 -0800 Subject: [PATCH 375/719] make a seperate test to verify that "close?" is called once during init and use caplog for this --- qcodes/tests/drivers/test_keithley_s46.py | 29 +++++++---------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index c5417f1fe1b..29beb918a31 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -1,4 +1,3 @@ -from io import StringIO import logging import pytest @@ -6,7 +5,6 @@ from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( S46, LockAcquisitionError ) -from qcodes.instrument.visa import VISA_LOGGER import qcodes.instrument.sims as sims visalib = sims.__file__.replace('__init__.py', 'Keithley_s46.yaml@sim') @@ -34,14 +32,7 @@ def s46_six(): """ A six channel-per-relay instrument """ - io_stream = StringIO() - handler = logging.StreamHandler(io_stream) - logger = logging.getLogger(VISA_LOGGER) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - driver = S46('s46_six', address='GPIB::2::INSTR', visalib=visalib) - driver.io_stream = io_stream yield driver driver.close() @@ -52,14 +43,7 @@ def s46_four(): """ A four channel-per-relay instrument """ - io_stream = StringIO() - handler = logging.StreamHandler(io_stream) - logger = logging.getLogger(VISA_LOGGER) - logger.setLevel(logging.DEBUG) - logger.addHandler(handler) - driver = S46('s46_four', address='GPIB::3::INSTR', visalib=visalib) - driver.io_stream = io_stream yield driver driver.close() @@ -78,12 +62,19 @@ def test_runtime_error_on_bad_init(): S46('s46_bad_state', address='GPIB::1::INSTR', visalib=visalib) +def test_query_close_once_at_init(caplog): + """ + Test that, during initialisation, we query the closed channels once only + """ + with caplog.at_level(logging.DEBUG): + S46('s46_test_query_once', address='GPIB::2::INSTR', visalib=visalib) + assert caplog.text.count(":CLOS?") == 1 + + def test_init_six(s46_six): """ Test that the six channel instrument initializes correctly. """ - log_messages = s46_six.io_stream.getvalue() - assert log_messages.count(":CLOS?") == 1 assert len(s46_six.available_channels) == 26 closed_channel_numbers = [1, 8, 13] @@ -96,8 +87,6 @@ def test_init_four(s46_four): """ Test that the six channel instrument initializes correctly. """ - log_messages = s46_four.io_stream.getvalue() - assert log_messages.count(":CLOS?") == 1 assert len(s46_four.available_channels) == 18 closed_channel_numbers = [1, 8] From ac94abb310a226875c55fff70e6bd48715055c08 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Fri, 7 Dec 2018 10:07:59 -0800 Subject: [PATCH 376/719] test that open_all_channels issues the right visa commands and locks are freed --- qcodes/tests/drivers/test_keithley_s46.py | 27 ++++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/qcodes/tests/drivers/test_keithley_s46.py b/qcodes/tests/drivers/test_keithley_s46.py index 29beb918a31..e9704e2f27e 100644 --- a/qcodes/tests/drivers/test_keithley_s46.py +++ b/qcodes/tests/drivers/test_keithley_s46.py @@ -1,5 +1,4 @@ import logging - import pytest from qcodes.instrument_drivers.tektronix.Keithley_s46 import ( @@ -64,14 +63,14 @@ def test_runtime_error_on_bad_init(): def test_query_close_once_at_init(caplog): """ - Test that, during initialisation, we query the closed channels once only + Test that, during initialisation, we query the closed channels only once """ with caplog.at_level(logging.DEBUG): S46('s46_test_query_once', address='GPIB::2::INSTR', visalib=visalib) assert caplog.text.count(":CLOS?") == 1 -def test_init_six(s46_six): +def test_init_six(s46_six, caplog): """ Test that the six channel instrument initializes correctly. """ @@ -82,6 +81,16 @@ def test_init_six(s46_six): S46.aliases[i] for i in closed_channel_numbers ] + with caplog.at_level(logging.DEBUG): + s46_six.open_all_channels() + assert ":open (@1)" in caplog.text + assert ":open (@8)" in caplog.text + assert ":open (@13)" in caplog.text + + assert s46_six.A1._lock._locked_by is None + assert s46_six.B1._lock._locked_by is None + assert s46_six.C1._lock._locked_by is None + def test_init_four(s46_four): """ @@ -120,6 +129,8 @@ def test_locking_mechanism(s46_six): more then once channel per replay 2) Test that the lock is released when opening a channel that was closed """ + s46_six.A1("close") + with pytest.raises( LockAcquisitionError, match="is already in use by channel" @@ -143,13 +154,3 @@ def test_locking_mechanism(s46_six): # Upon opening C1 we should be able to close C2 s46_six.C1("open") s46_six.C2("close") - - -def test_open_all(s46_six): - """ - Verify that calling 'open_all_channels' does not cause an exception. - Unfortunately, pyvisa-sim is not flexible enough for us to test if channels - have truly opened. - """ - s46_six.open_all_channels() - From 74dd9dfd49292e8b18ec53a898fa60bdff05a47d Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 13:16:00 +0100 Subject: [PATCH 377/719] improve docstrings --- qcodes/dataset/sqlite_base.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 13425a74a05..6e1f2e6beeb 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1228,9 +1228,17 @@ def get_parameter_data(conn: ConnectionPlus, Dict[str, Dict[str, np.ndarray]]: """ Get data for one or more parameters and its dependencies. The data - is returned as numpy arrays nested 2 layers of dicts. The keys or the - outermost are the requested parameters and the second level by the loaded - parameters. + is returned as numpy arrays within 2 layers of nested dicts. The keys of + the outermost dict are the requested parameters and the keys of the second + level are the loaded parameters (requested parameter followed by its + dependencies). Start and End sllows one to specify a range of rows + (1-based indexing, both ends are included). + + Note that this assumes that all array type parameters have the same length. + This should always be the case for a parameter and its dependencies. + + Note that all numeric data will at the moment be returned as floating point + values. Args: conn: database connection @@ -1260,7 +1268,6 @@ def get_parameter_data(conn: ConnectionPlus, # if we have array type parameters expand all other parameters # to arrays if 'array' in types and ('numeric' in types or 'text' in types): - # todo: Should we check that all the arrays are the same size? first_array_element = types.index('array') numeric_elms = [i for i, x in enumerate(types) if x == "numeric"] @@ -1272,6 +1279,10 @@ def get_parameter_data(conn: ConnectionPlus, row[element], dtype=np.float) # todo should we handle int/float types here + # we would in practice have to perform another + # loop to check that all elements of a given can be cast to + # int without loosing precision before choosing an interger + # representation of the array for element in text_elms: strlen = len(row[element]) row[element] = np.full_like(row[first_array_element], @@ -1280,7 +1291,6 @@ def get_parameter_data(conn: ConnectionPlus, # Benchmarking shows that transposing the data with python types is # faster than transposing the data using np.array.transpose - # This method is going to form the entry point for a compiled version res_t = list(map(list, zip(*res))) output[output_param] = {name: np.squeeze(np.array(column_data)) for name, column_data @@ -1536,7 +1546,7 @@ def get_non_dependencies(conn: ConnectionPlus, run_id: The run_id of the run in question Returns: - + A list of the parameter names. """ parameters = get_parameters(conn, run_id) maybe_independent = [] @@ -1562,14 +1572,17 @@ def get_non_dependencies(conn: ConnectionPlus, def get_parameter_dependencies(conn: ConnectionPlus, param: str, run_id: int) -> List[ParamSpec]: """ - Given a parameter name return the ParamSpec of the parameter along with - the ParamSpecs of all it's dependencies. + Given a parameter name return a list of ParamSpecs where the first + element is the ParamSpec of the given parameter and the rest of the + elements are ParamSpecs of its dependencies. Args: - conn: - param: - run_id: + conn: connection to the database + param: the name of the parameter to look up + run_id: run_id: The run_id of the run in question + Returns: + List of ParameterSpecs of the parameter followed by its dependencies. """ layout_id = get_layout_id(conn, param, run_id) deps = get_dependencies(conn, layout_id) From 96fcae00cdc362e6ea9910181559141a058d69fa Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 13:45:29 +0100 Subject: [PATCH 378/719] ensure thet the expeced results do no miss an element --- qcodes/tests/dataset/helper_functions.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 87b68c1c4a2..16a80ce107b 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -13,12 +13,15 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], Args: data: The data to verify parameter_names: names of the parameters requested - expected_names: names of the paramerters expected to be loaded - expected_shapes: shapes of the paramters loaded + expected_names: names of the parameters expected to be loaded + expected_shapes: shapes of the parameters loaded Returns: """ + # check that all the expected parameters in the dict are + # included in the list of parameters + assert all(param in parameter_names for param in list(data.keys())) is True for param in parameter_names: innerdata = data[param] verify_data_dict_for_single_param(innerdata, From 75b85c7b3b933f07d8e64e4e8c1e12e9bde7cbd4 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 14:03:46 +0100 Subject: [PATCH 379/719] Test removing one element --- qcodes/tests/dataset/test_dataset_basic.py | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 240ee680440..f15132fb645 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1,6 +1,7 @@ import itertools from copy import copy import re +import random import pytest import numpy as np @@ -891,12 +892,30 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset expected_shapes) -def parameter_test_helper(ds, toplevel_names, expected_names, expected_shapes): +def parameter_test_helper(ds, toplevel_names, + expected_names, + expected_shapes): data = ds.get_parameter_data(*toplevel_names) all_data = ds.get_parameter_data() - assert data.keys() == all_data.keys() + all_parameters = list(all_data.keys()) + assert set(data.keys()).issubset(set(all_parameters)) assert len(data.keys()) == len(toplevel_names) verify_data_dict(data, toplevel_names, expected_names, expected_shapes) verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes) + + # now lets remove a random element from the list + # and test that we don't get data back for that element. + # This only makes sense if there originally where more than + # one parameter in the list + if len(all_parameters) > 1: + elem_to_remove = random.randint(0, len(toplevel_names) - 1) + subset_names = copy(all_parameters) + name_removed = subset_names.pop(elem_to_remove) + expected_names.pop(name_removed) + expected_shapes.pop(name_removed) + + subset_data = ds.get_parameter_data(*subset_names) + verify_data_dict(subset_data, subset_names, expected_names, + expected_shapes) From d7f7fb7f790c81fbf86152030316365ba5f70600 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 14:09:03 +0100 Subject: [PATCH 380/719] Continue removing until there is only one element --- qcodes/tests/dataset/test_dataset_basic.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index f15132fb645..8b30f1aeafa 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -905,13 +905,11 @@ def parameter_test_helper(ds, toplevel_names, verify_data_dict(data, toplevel_names, expected_names, expected_shapes) verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes) - # now lets remove a random element from the list - # and test that we don't get data back for that element. - # This only makes sense if there originally where more than - # one parameter in the list - if len(all_parameters) > 1: - elem_to_remove = random.randint(0, len(toplevel_names) - 1) - subset_names = copy(all_parameters) + # Now lets remove a random element from the list + # We do this one by one until there is only one element in the list + subset_names = copy(all_parameters) + while len(subset_names) > 1: + elem_to_remove = random.randint(0, len(subset_names) - 1) name_removed = subset_names.pop(elem_to_remove) expected_names.pop(name_removed) expected_shapes.pop(name_removed) From 442c4bfc5743035e4249c898697aea46975bb88a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 14:23:49 +0100 Subject: [PATCH 381/719] Test content of data arrays --- qcodes/tests/dataset/helper_functions.py | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 16a80ce107b..8fd37dbdc7c 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -1,22 +1,25 @@ from typing import Sequence, Tuple, Dict import numpy as np - +from numpy.testing import assert_allclose def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], parameter_names: Sequence[str], expected_names: Dict[str, Sequence[str]], - expected_shapes: Dict[str, Sequence[Tuple[int, ...]]]) -> None: + expected_shapes: Dict[str, Sequence[Tuple[int, ...]]], + expected_values: Dict[str, Sequence[np.ndarray]]) -> None: """ Simple helper function to verify a dict of data Args: - data: The data to verify - parameter_names: names of the parameters requested - expected_names: names of the parameters expected to be loaded - expected_shapes: shapes of the parameters loaded - - Returns: + data: The dict data to verify the shape and content of. + parameter_names: names of the parameters loaded as top level + keys in the dict. + expected_names: names of the parameters expected as keys in the second + level. + expected_shapes: expected shapes of the parameters loaded in the values + of the dict. + expected_values: expected content of the data arrays. """ # check that all the expected parameters in the dict are @@ -26,11 +29,14 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], innerdata = data[param] verify_data_dict_for_single_param(innerdata, expected_names[param], - expected_shapes[param]) + expected_shapes[param], + expected_values[param]) def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], names: Sequence[str], - shapes: Sequence[Tuple[int, ...]]): - for name, shape in zip(names, shapes): + shapes: Sequence[Tuple[int, ...]], + values): + for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape + np.testing.assert_allclose(datadict[name], value) From 5719317a3869c870f313181aaf45bcd08eca3e11 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 14:24:21 +0100 Subject: [PATCH 382/719] Convert testing of scalar data --- qcodes/tests/dataset/dataset_fixtures.py | 5 +++-- qcodes/tests/dataset/test_dataset_basic.py | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index bd1a749f8f2..d7c64eaa00c 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -27,8 +27,9 @@ def scalar_dataset(dataset): depends_on=params_indep)] for p in params: dataset.add_parameter(p) - dataset.add_results([{p.name: np.random.rand(1)[0] for p in params} - for _ in range(n_rows)]) + dataset.add_results([{p.name: np.int(n_rows*10*pn+i) + for pn, p in enumerate(params)} + for i in range(n_rows)]) dataset.mark_complete() yield dataset diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 8b30f1aeafa..474520d4d93 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -777,7 +777,6 @@ def test_get_data_with_start_and_end_args(self, ds_with_vals, def test_get_parameter_data(scalar_dataset): - ds = scalar_dataset input_names = ['param_3'] expected_names = {} @@ -785,11 +784,15 @@ def test_get_parameter_data(scalar_dataset): 'param_3'] expected_shapes = {} expected_shapes['param_3'] = [(10**3, )]*4 + expected_values = {} + expected_values['param_3'] = [np.arange(10000*a, 10000*a+1000) + for a in range(4)] parameter_test_helper(scalar_dataset, input_names, expected_names, - expected_shapes) + expected_shapes, + expected_values) def test_get_array_parameter_data(array_dataset): @@ -894,7 +897,8 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset def parameter_test_helper(ds, toplevel_names, expected_names, - expected_shapes): + expected_shapes, + expected_values): data = ds.get_parameter_data(*toplevel_names) all_data = ds.get_parameter_data() @@ -902,8 +906,10 @@ def parameter_test_helper(ds, toplevel_names, assert set(data.keys()).issubset(set(all_parameters)) assert len(data.keys()) == len(toplevel_names) - verify_data_dict(data, toplevel_names, expected_names, expected_shapes) - verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes) + verify_data_dict(data, toplevel_names, expected_names, expected_shapes, + expected_values) + verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes, + expected_values) # Now lets remove a random element from the list # We do this one by one until there is only one element in the list @@ -913,7 +919,8 @@ def parameter_test_helper(ds, toplevel_names, name_removed = subset_names.pop(elem_to_remove) expected_names.pop(name_removed) expected_shapes.pop(name_removed) + expected_values.pop(name_removed) subset_data = ds.get_parameter_data(*subset_names) verify_data_dict(subset_data, subset_names, expected_names, - expected_shapes) + expected_shapes, expected_values) From e91387a1fa1401088bb55bf42f12f0ffbe0a388a Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 14:45:04 +0100 Subject: [PATCH 383/719] add shapes to 2 more tests --- qcodes/tests/dataset/test_dataset_basic.py | 39 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 474520d4d93..aa46df7c995 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -802,12 +802,17 @@ def test_get_array_parameter_data(array_dataset): expected_names = {} expected_names['testparameter'] = ['testparameter', 'this_setpoint'] expected_shapes = {} - expected_shapes['testparameter'] = [(5, ), (5, )] + expected_len = 5 + expected_shapes['testparameter'] = [(expected_len, ), (expected_len, )] + expected_values = {} + expected_values['testparameter'] = [np.ones(expected_len) + 1, + np.linspace(5, 9, expected_len)] parameter_test_helper(array_dataset, input_names, expected_names, - expected_shapes) + expected_shapes, + expected_values) def test_get_multi_parameter_data(multi_dataset): @@ -820,16 +825,39 @@ def test_get_multi_parameter_data(multi_dataset): expected_names['this'] = ['this', 'this_setpoint', 'that_setpoint'] expected_names['that'] = ['that', 'this_setpoint', 'that_setpoint'] expected_shapes = {} + expected_values = {} + shape_1 = 5 + shape_2 = 3 + + this_data = np.zeros((shape_1, shape_2)) + that_data = np.ones((shape_1, shape_2)) + sp_1_data = np.tile(np.linspace(5, 9, shape_1).reshape(shape_1, 1), + (1, shape_2)) + sp_2_data = np.tile(np.linspace(9, 11, shape_2), (shape_1, 1)) if 'array' in types: - expected_shapes['this'] = [(5, 3), (5, 3)] - expected_shapes['that'] = [(5, 3), (5, 3)] + expected_shapes['this'] = [(shape_1, shape_2), (shape_1, shape_2)] + expected_shapes['that'] = [(shape_1, shape_2), (shape_1, shape_2)] + expected_values['this'] = [this_data, + sp_1_data, + sp_2_data] + expected_values['that'] = [that_data, + sp_1_data, + sp_2_data] + else: expected_shapes['this'] = [(15,), (15,)] expected_shapes['that'] = [(15,), (15,)] + expected_values['this'] = [this_data.ravel(), + sp_1_data.ravel(), + sp_2_data.ravel()] + expected_values['that'] = [that_data.ravel(), + sp_1_data.ravel(), + sp_2_data.ravel()] parameter_test_helper(multi_dataset, input_names, expected_names, - expected_shapes) + expected_shapes, + expected_values) def test_get_array_in_scalar_param_data(array_in_scalar_dataset): @@ -899,6 +927,7 @@ def parameter_test_helper(ds, toplevel_names, expected_names, expected_shapes, expected_values): + data = ds.get_parameter_data(*toplevel_names) all_data = ds.get_parameter_data() From 25c0bcdbd0318fb97c8686b10136933b90f763fb Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 15:41:29 +0100 Subject: [PATCH 384/719] update one more test --- qcodes/tests/dataset/test_dataset_basic.py | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index aa46df7c995..fe74f216250 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -870,14 +870,35 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset): expected_names['testparameter'] = ['testparameter', 'scalarparam', 'this_setpoint'] expected_shapes = {} + + shape_1 = 9 + shape_2 = 5 + + test_parameter_values = np.tile((np.ones(shape_2) + 1).reshape(1, shape_2), + (shape_1, 1)) + scalar_param_values = np.tile(np.arange(1, 10).reshape(shape_1, 1), + (1, shape_2)) + setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), + (shape_1, 1)) + expected_shapes['testparameter'] = {} + expected_values = {} if 'array' in types: expected_shapes['testparameter'] = [(9, 5), (9, 5)] + expected_values['testparameter'] = [ + test_parameter_values, + scalar_param_values, + setpoint_param_values] else: expected_shapes['testparameter'] = [(45,), (45,)] + expected_values['testparameter'] = [ + test_parameter_values.ravel(), + scalar_param_values.ravel(), + setpoint_param_values.ravel()] parameter_test_helper(array_in_scalar_dataset, input_names, expected_names, - expected_shapes) + expected_shapes, + expected_values) def test_get_array_in_str_param_data(array_in_str_dataset): From f15f6abaae15cfc159f91ddb38e80b5506d97f95 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 16:08:28 +0100 Subject: [PATCH 385/719] Add expected results to last 2 tests --- qcodes/tests/dataset/test_dataset_basic.py | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index fe74f216250..8084b680737 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -911,14 +911,36 @@ def test_get_array_in_str_param_data(array_in_str_dataset): expected_names['testparameter'] = ['testparameter', 'textparam', 'this_setpoint'] expected_shapes = {} + + shape_1 = 3 + shape_2 = 5 + + test_parameter_values = np.tile((np.ones(shape_2) + 1).reshape(1, shape_2), + (shape_1, 1)) + scalar_param_values = np.tile(np.array(['A', 'B', 'C']).reshape(shape_1, 1), + (1, shape_2)) + setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), + (shape_1, 1)) + expected_shapes['testparameter'] = {} + expected_values = {} + if 'array' in types: expected_shapes['testparameter'] = [(3, 5), (3, 5)] + expected_values['testparameter'] = [ + test_parameter_values, + scalar_param_values, + setpoint_param_values] else: expected_shapes['testparameter'] = [(15,), (15,)] + expected_values['testparameter'] = [ + test_parameter_values.ravel(), + scalar_param_values.ravel(), + setpoint_param_values.ravel()] parameter_test_helper(array_in_str_dataset, input_names, expected_names, - expected_shapes) + expected_shapes, + expected_values) def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): @@ -931,17 +953,24 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset expected_names = {} expected_names['param_1'] = [] expected_names['param_2'] = [] - expected_names['param_3'] = ['param_0'] + expected_names['param_3'] = ['param_3', 'param_0'] expected_shapes = {} expected_shapes['param_1'] = [(10 ** 3,)] expected_shapes['param_2'] = [(10 ** 3,)] expected_shapes['param_3'] = [(10**3, )]*2 + expected_values = {} + expected_values['param_1'] = [np.arange(10000, 10000 + 1000)] + expected_values['param_2'] = [np.arange(20000, 20000 + 1000)] + expected_values['param_3'] = [np.arange(30000, 30000 + 1000), + np.arange(0, 1000)] + parameter_test_helper(ds, expected_toplevel_params, expected_names, - expected_shapes) + expected_shapes, + expected_values) def parameter_test_helper(ds, toplevel_names, From d1d06f50f17d72362d6cc15e694e13783746de71 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 16:22:09 +0100 Subject: [PATCH 386/719] Add missing data --- qcodes/tests/dataset/test_dataset_basic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 8084b680737..254914ceb51 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -951,8 +951,8 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset assert params == expected_toplevel_params expected_names = {} - expected_names['param_1'] = [] - expected_names['param_2'] = [] + expected_names['param_1'] = ['param_1'] + expected_names['param_2'] = ['param_2'] expected_names['param_3'] = ['param_3', 'param_0'] expected_shapes = {} From ba504db70c62ac75a1f2f98f935f90b20b90286d Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 16:26:10 +0100 Subject: [PATCH 387/719] No need to use close. This should match exactly. That also works for strings. --- qcodes/tests/dataset/helper_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 8fd37dbdc7c..80e0b0c11bf 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -39,4 +39,4 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], values): for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape - np.testing.assert_allclose(datadict[name], value) + np.testing.assert_array_equal(datadict[name], value) From 15a837748d1d840e3307d936f99b9302c40aaaf1 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 16:26:22 +0100 Subject: [PATCH 388/719] Add an extra assert --- qcodes/tests/dataset/helper_functions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 80e0b0c11bf..1548963df0e 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -37,6 +37,8 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], names: Sequence[str], shapes: Sequence[Tuple[int, ...]], values): + # check that there are no unexpected elements in the dict + assert all(param in names for param in list(datadict.keys())) is True for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape np.testing.assert_array_equal(datadict[name], value) From 7ecb914ad4e9584abe7746ab42b5ac13513fe237 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 16:50:07 +0100 Subject: [PATCH 389/719] Update fixtures to match expected result --- qcodes/tests/dataset/dataset_fixtures.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index d7c64eaa00c..a58365bf52a 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -124,7 +124,8 @@ def standalone_parameters_dataset(dataset): depends_on=params_indep[0:1])] for p in params: dataset.add_parameter(p) - dataset.add_results([{p.name: np.random.rand(1)[0] for p in params} - for _ in range(n_rows)]) + dataset.add_results([{p.name: np.int(n_rows*10*pn+i) + for pn, p in enumerate(params)} + for i in range(n_rows)]) dataset.mark_complete() yield dataset From 4338a1fc792603a1f6c60090b5f87955c4fde945 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 10 Dec 2018 18:40:46 +0100 Subject: [PATCH 390/719] update sqlite tests --- qcodes/tests/dataset/test_sqlite_base.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index fc408c7ef51..93ec6dc0d96 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -215,7 +215,11 @@ def test_get_parameter_data(scalar_dataset): expected_shapes = {} expected_shapes['param_3'] = [(10**3, )]*4 - verify_data_dict(data, input_names, expected_names, expected_shapes) + expected_values = {} + expected_values['param_3'] = [np.arange(10000*a, 10000*a+1000) + for a in range(4)] + verify_data_dict(data, input_names, expected_names, expected_shapes, + expected_values) def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): @@ -230,17 +234,23 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset assert len(data.keys()) == len(expected_toplevel_params) expected_names = {} - expected_names['param_1'] = [] - expected_names['param_2'] = [] - expected_names['param_3'] = ['param_0'] + expected_names['param_1'] = ['param_1'] + expected_names['param_2'] = ['param_2'] + expected_names['param_3'] = ['param_3', 'param_0'] expected_shapes = {} expected_shapes['param_1'] = [(10 ** 3,)] expected_shapes['param_2'] = [(10 ** 3,)] expected_shapes['param_3'] = [(10**3, )]*2 + expected_values = {} + expected_values['param_1'] = [np.arange(10000, 10000 + 1000)] + expected_values['param_2'] = [np.arange(20000, 20000 + 1000)] + expected_values['param_3'] = [np.arange(30000, 30000 + 1000), + np.arange(0, 1000)] + verify_data_dict(data, expected_toplevel_params, expected_names, - expected_shapes) + expected_shapes, expected_values) def test_is_run_id_in_db(empty_temp_db): From a9a9739d9fe05d3fc0fb5bf2e4f6fef3d4bbb2c8 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 11 Dec 2018 10:51:55 +0100 Subject: [PATCH 391/719] Cleanup import --- qcodes/tests/dataset/helper_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 1548963df0e..e74a4b84142 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -1,7 +1,7 @@ from typing import Sequence, Tuple, Dict import numpy as np -from numpy.testing import assert_allclose +from numpy.testing import assert_array_equal def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], parameter_names: Sequence[str], @@ -41,4 +41,4 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], assert all(param in names for param in list(datadict.keys())) is True for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape - np.testing.assert_array_equal(datadict[name], value) + assert_array_equal(datadict[name], value) From 35781210108c94b9b338fbb9f55b58a7cdc6e331 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 11 Dec 2018 11:20:40 +0100 Subject: [PATCH 392/719] typo --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 6e1f2e6beeb..6a9643524c5 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1281,7 +1281,7 @@ def get_parameter_data(conn: ConnectionPlus, # todo should we handle int/float types here # we would in practice have to perform another # loop to check that all elements of a given can be cast to - # int without loosing precision before choosing an interger + # int without loosing precision before choosing an integer # representation of the array for element in text_elms: strlen = len(row[element]) From e2c9298aa6f4d07af58bc65f9c17cb5df39e0a04 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 11 Dec 2018 16:16:56 +0100 Subject: [PATCH 393/719] build feature branch --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 55c548856f8..685b50a574e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ python: branches: only: - master + - DataStorageInterface # command to install dependencies and qcodes # We want to fail early if there is an installation problem, so From 17f311642af5ea18f6f5840eaa55ae90d6030429 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Dec 2018 14:02:17 +0100 Subject: [PATCH 394/719] Ensure that we still get an array in the case where we request exactly one result --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 6a9643524c5..71215dbcce1 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1292,7 +1292,7 @@ def get_parameter_data(conn: ConnectionPlus, # Benchmarking shows that transposing the data with python types is # faster than transposing the data using np.array.transpose res_t = list(map(list, zip(*res))) - output[output_param] = {name: np.squeeze(np.array(column_data)) + output[output_param] = {name: np.atleast_1d(np.squeeze(np.array(column_data))) for name, column_data in zip(param_names, res_t)} return output From c9433591c438d0c1722f70474c439c6c87e6e939 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Dec 2018 14:17:07 +0100 Subject: [PATCH 395/719] Start testing start and end --- qcodes/tests/dataset/test_dataset_basic.py | 50 +++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 254914ceb51..d00eadb2ecf 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -776,7 +776,9 @@ def test_get_data_with_start_and_end_args(self, ds_with_vals, assert expected == ds_with_vals.get_data(self.x, start=start, end=end) -def test_get_parameter_data(scalar_dataset): +@given(start=hst.one_of(hst.integers(1, 10**3), hst.none()), + end=hst.one_of(hst.integers(1, 10**3), hst.none())) +def test_get_parameter_data(scalar_dataset, start, end): input_names = ['param_3'] expected_names = {} @@ -788,11 +790,17 @@ def test_get_parameter_data(scalar_dataset): expected_values['param_3'] = [np.arange(10000*a, 10000*a+1000) for a in range(4)] + start, end = limit_data_to_start_end(start, end, input_names, + expected_names, expected_shapes, + expected_values) + parameter_test_helper(scalar_dataset, input_names, expected_names, expected_shapes, - expected_values) + expected_values, + start, + end) def test_get_array_parameter_data(array_dataset): @@ -976,10 +984,12 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset def parameter_test_helper(ds, toplevel_names, expected_names, expected_shapes, - expected_values): + expected_values, + start=None, + end=None): - data = ds.get_parameter_data(*toplevel_names) - all_data = ds.get_parameter_data() + data = ds.get_parameter_data(*toplevel_names, start=start, end=end) + all_data = ds.get_parameter_data(start=start, end=end) all_parameters = list(all_data.keys()) assert set(data.keys()).issubset(set(all_parameters)) @@ -1000,6 +1010,34 @@ def parameter_test_helper(ds, toplevel_names, expected_shapes.pop(name_removed) expected_values.pop(name_removed) - subset_data = ds.get_parameter_data(*subset_names) + subset_data = ds.get_parameter_data(*subset_names, + start=start, end=end) verify_data_dict(subset_data, subset_names, expected_names, expected_shapes, expected_values) + + +def limit_data_to_start_end(start, end, input_names, expected_names, + expected_shapes, expected_values): + if not (start is None and end is None): + if start is None: + start = 1 + elif end is None: + # all the shapes are the same so pick the first one + end = expected_shapes[input_names[0]][0][0] + if end < start: + for name in input_names: + expected_names[name] = [] + expected_shapes[name] = () + expected_values[name] = {} + else: + for name in input_names: + new_shapes = [] + for shape in expected_shapes[name]: + shape_list = list(shape) + shape_list[0] = end - start + 1 + new_shapes.append(tuple(shape_list)) + expected_shapes[name] = new_shapes + for i in range(len(expected_values[name])): + expected_values[name][i] = \ + expected_values[name][i][start - 1:end] + return start, end From 9ad90bf79b0fe6c9e7e43ea68e24acf5cb7aad04 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Dec 2018 15:44:52 +0100 Subject: [PATCH 396/719] Don't squeeze singleton dimension. This leads to inconsistent results --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 71215dbcce1..9c18f02f236 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -1292,7 +1292,7 @@ def get_parameter_data(conn: ConnectionPlus, # Benchmarking shows that transposing the data with python types is # faster than transposing the data using np.array.transpose res_t = list(map(list, zip(*res))) - output[output_param] = {name: np.atleast_1d(np.squeeze(np.array(column_data))) + output[output_param] = {name: np.array(column_data) for name, column_data in zip(param_names, res_t)} return output From ea8444cebb89af59bcabddd07bf768fe778450cb Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Dec 2018 15:47:06 +0100 Subject: [PATCH 397/719] Update tests to reflect changes in dims --- qcodes/tests/dataset/test_dataset_basic.py | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index d00eadb2ecf..8e227fe869f 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -804,18 +804,23 @@ def test_get_parameter_data(scalar_dataset, start, end): def test_get_array_parameter_data(array_dataset): - + paramspecs = array_dataset.paramspecs + types = [param.type for param in paramspecs.values()] input_names = ['testparameter'] expected_names = {} expected_names['testparameter'] = ['testparameter', 'this_setpoint'] expected_shapes = {} expected_len = 5 - expected_shapes['testparameter'] = [(expected_len, ), (expected_len, )] + expected_shapes['testparameter'] = [(expected_len,), (expected_len,)] expected_values = {} expected_values['testparameter'] = [np.ones(expected_len) + 1, np.linspace(5, 9, expected_len)] - + if 'array' in types: + expected_shapes['testparameter'] = [(1, expected_len), + (1, expected_len)] + for i in range(len(expected_values['testparameter'])): + expected_values['testparameter'][i] = expected_values['testparameter'][i].reshape(1, expected_len) parameter_test_helper(array_dataset, input_names, expected_names, @@ -843,14 +848,14 @@ def test_get_multi_parameter_data(multi_dataset): (1, shape_2)) sp_2_data = np.tile(np.linspace(9, 11, shape_2), (shape_1, 1)) if 'array' in types: - expected_shapes['this'] = [(shape_1, shape_2), (shape_1, shape_2)] - expected_shapes['that'] = [(shape_1, shape_2), (shape_1, shape_2)] - expected_values['this'] = [this_data, - sp_1_data, - sp_2_data] - expected_values['that'] = [that_data, - sp_1_data, - sp_2_data] + expected_shapes['this'] = [(1, shape_1, shape_2), (1, shape_1, shape_2)] + expected_shapes['that'] = [(1, shape_1, shape_2), (1, shape_1, shape_2)] + expected_values['this'] = [this_data.reshape(1, shape_1, shape_2), + sp_1_data.reshape(1, shape_1, shape_2), + sp_2_data.reshape(1, shape_1, shape_2)] + expected_values['that'] = [that_data.reshape(1, shape_1, shape_2), + sp_1_data.reshape(1, shape_1, shape_2), + sp_2_data.reshape(1, shape_1, shape_2)] else: expected_shapes['this'] = [(15,), (15,)] From 150f31a495b521ae9f7b579a4ad726ff423880a1 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 12 Dec 2018 16:15:05 +0100 Subject: [PATCH 398/719] Split test to allow hypothesis to generate the correct start and end values --- qcodes/tests/dataset/dataset_fixtures.py | 27 ++++++-- qcodes/tests/dataset/test_dataset_basic.py | 75 ++++++++++++++++------ 2 files changed, 80 insertions(+), 22 deletions(-) diff --git a/qcodes/tests/dataset/dataset_fixtures.py b/qcodes/tests/dataset/dataset_fixtures.py index a58365bf52a..7cdcfbffcf2 100644 --- a/qcodes/tests/dataset/dataset_fixtures.py +++ b/qcodes/tests/dataset/dataset_fixtures.py @@ -65,15 +65,34 @@ def multi_dataset(experiment, request): datasaver.dataset.conn.close() -@pytest.fixture(scope="function", - params=["array", "numeric"]) -def array_in_scalar_dataset(experiment, request): +@pytest.fixture(scope="function") +def array_in_scalar_dataset(experiment): meas = Measurement() scalar_param = Parameter('scalarparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param) meas.register_parameter(param, setpoints=(scalar_param,), - paramtype=request.param) + paramtype='array') + + with meas.run() as datasaver: + for i in range(1, 10): + scalar_param.set(i) + datasaver.add_result((scalar_param, scalar_param.get()), + (param, param.get())) + try: + yield datasaver.dataset + finally: + datasaver.dataset.conn.close() + + +@pytest.fixture(scope="function") +def array_in_scalar_dataset_unrolled(experiment): + meas = Measurement() + scalar_param = Parameter('scalarparam', set_cmd=None) + param = ArraySetPointParam() + meas.register_parameter(scalar_param) + meas.register_parameter(param, setpoints=(scalar_param,), + paramtype='numeric') with meas.run() as datasaver: for i in range(1, 10): diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 8e227fe869f..100753be42d 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -25,7 +25,7 @@ experiment, dataset) from qcodes.tests.dataset.dataset_fixtures import scalar_dataset, \ array_dataset, multi_dataset, array_in_scalar_dataset, array_in_str_dataset, \ - standalone_parameters_dataset + standalone_parameters_dataset, array_in_scalar_dataset_unrolled # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs @@ -873,10 +873,10 @@ def test_get_multi_parameter_data(multi_dataset): expected_values) -def test_get_array_in_scalar_param_data(array_in_scalar_dataset): - paramspecs = array_in_scalar_dataset.paramspecs - types = [param.type for param in paramspecs.values()] - +@given(start=hst.one_of(hst.integers(1, 9), hst.none()), + end=hst.one_of(hst.integers(1, 9), hst.none())) +def test_get_array_in_scalar_param_data(array_in_scalar_dataset, + start, end): input_names = ['testparameter'] expected_names = {} @@ -894,24 +894,63 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset): setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), (shape_1, 1)) expected_shapes['testparameter'] = {} + expected_shapes['testparameter'] = [(9, 5), (9, 5)] expected_values = {} - if 'array' in types: - expected_shapes['testparameter'] = [(9, 5), (9, 5)] - expected_values['testparameter'] = [ - test_parameter_values, - scalar_param_values, - setpoint_param_values] - else: - expected_shapes['testparameter'] = [(45,), (45,)] - expected_values['testparameter'] = [ - test_parameter_values.ravel(), - scalar_param_values.ravel(), - setpoint_param_values.ravel()] + expected_values['testparameter'] = [ + test_parameter_values, + scalar_param_values, + setpoint_param_values] + + start, end = limit_data_to_start_end(start, end, input_names, + expected_names, expected_shapes, + expected_values) parameter_test_helper(array_in_scalar_dataset, input_names, expected_names, expected_shapes, - expected_values) + expected_values, + start, + end) + + +@given(start=hst.one_of(hst.integers(1, 45), hst.none()), + end=hst.one_of(hst.integers(1, 45), hst.none())) +def test_get_array_in_scalar_param_unrolled(array_in_scalar_dataset_unrolled, + start, end): + input_names = ['testparameter'] + + expected_names = {} + expected_names['testparameter'] = ['testparameter', 'scalarparam', + 'this_setpoint'] + expected_shapes = {} + + shape_1 = 9 + shape_2 = 5 + + test_parameter_values = np.tile((np.ones(shape_2) + 1).reshape(1, shape_2), + (shape_1, 1)) + scalar_param_values = np.tile(np.arange(1, 10).reshape(shape_1, 1), + (1, shape_2)) + setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), + (shape_1, 1)) + expected_shapes['testparameter'] = {} + expected_shapes['testparameter'] = [(45,), (45,)] + expected_values = {} + expected_values['testparameter'] = [ + test_parameter_values.ravel(), + scalar_param_values.ravel(), + setpoint_param_values.ravel()] + + start, end = limit_data_to_start_end(start, end, input_names, + expected_names, expected_shapes, + expected_values) + parameter_test_helper(array_in_scalar_dataset_unrolled, + input_names, + expected_names, + expected_shapes, + expected_values, + start, + end) def test_get_array_in_str_param_data(array_in_str_dataset): From 37901e106bf9fb8937e9f5619b2f234a69d665f5 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 13 Dec 2018 10:00:24 +0100 Subject: [PATCH 399/719] Remove some magic numbers --- qcodes/tests/dataset/test_dataset_basic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 100753be42d..58e49386ec1 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -894,7 +894,7 @@ def test_get_array_in_scalar_param_data(array_in_scalar_dataset, setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), (shape_1, 1)) expected_shapes['testparameter'] = {} - expected_shapes['testparameter'] = [(9, 5), (9, 5)] + expected_shapes['testparameter'] = [(shape_1, shape_2), (shape_1, shape_2)] expected_values = {} expected_values['testparameter'] = [ test_parameter_values, @@ -934,7 +934,7 @@ def test_get_array_in_scalar_param_unrolled(array_in_scalar_dataset_unrolled, setpoint_param_values = np.tile((np.linspace(5, 9, shape_2)).reshape(1, shape_2), (shape_1, 1)) expected_shapes['testparameter'] = {} - expected_shapes['testparameter'] = [(45,), (45,)] + expected_shapes['testparameter'] = [(shape_1*shape_2,), (shape_1*shape_2,)] expected_values = {} expected_values['testparameter'] = [ test_parameter_values.ravel(), From 3753a1591500d8a802ee4b2e69d9c936d2d44157 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 13 Dec 2018 20:31:00 +0100 Subject: [PATCH 400/719] Require websockets >=7.0 https://github.com/QCoDeS/Qcodes/pull/1407 broke support for older versions --- environment.yml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/environment.yml b/environment.yml index 9bd0a05354a..2aca03ca0bd 100644 --- a/environment.yml +++ b/environment.yml @@ -28,5 +28,5 @@ dependencies: - testpath>=0.4.2 # 0.4.1 is bad due to https://github.com/conda-forge/testpath-feedstock/issues/7 - tqdm - pip: - - websockets>=3.2 + - websockets>=7.0 - broadbean>=0.9.1 diff --git a/setup.py b/setup.py index a90ef6a89be..15cf520aff8 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ def readme(): 'numpy>=1.10', 'pyvisa>=1.9.1', 'h5py>=2.6', - 'websockets>=3.2', + 'websockets>=7.0', 'jsonschema', 'pyzmq', 'wrapt', From 3118de7da403322a797b1e23decda841d1a664a0 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 19 Dec 2018 17:05:14 -0800 Subject: [PATCH 401/719] added function to parse a curve file --- .../instrument_drivers/Lakeshore/Model_325.py | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index 4b174c11951..58258a557aa 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -1,11 +1,65 @@ import numpy as np -from typing import cast +from typing import cast, Union, List, Tuple, Iterable +from itertools import takewhile, repeat from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum, Numbers from qcodes.instrument.group_parameter import GroupParameter, Group +def read_curve_file(file_path: str) -> dict: + """ + Read a curve file with extension *.330 + The format of the file is as follows: + + Item1: value + Item2: value + Item3: value + + Header1 Header2 Header3 + data11 data12 data13 + data21 data22 data23 + """ + + def split_data_line( + line: str, + parsers: Union[type, List]=str + ) -> List[str]: + + if not isinstance(parsers, list): + parsers = repeat(parsers) + + line_split = [i for i in line.split(" ") if i != ""] + + return [ + parser(i) for parser, i in zip(parsers, line_split) + ] + + def strip(strings: Iterable[str]) -> Tuple: + return tuple(s.strip() for s in strings) + + with open(file_path, "r") as curve_file: + file_content = curve_file.read() + + lines = iter(file_content.split("\n")) + # Meta data lines contain a colon + metadata_lines = takewhile(lambda s: ":" in s, lines) + curve_data = dict([strip(line.split(":")) for line in metadata_lines]) + # After meta data we have a data header + header_items = strip(split_data_line(next(lines))) + # After that we have the curve data + data = [ + split_data_line(line, parsers=float) + for line in lines if line != "" + ] + + curve_data["data"] = dict( + zip(header_items, zip(*data)) + ) + + return curve_data + + class Model_325_Curve(InstrumentChannel): valid_sensor_units = ["mV", "V", "Ohm", "log Ohm"] From f6ba46e002b054d436efed69111c90f740f41a73 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 19 Dec 2018 18:53:42 -0800 Subject: [PATCH 402/719] 1) add driver method to upload a curve from file 2) bug fix in "upload_curve": should be index - 1 when selecting the right curve --- .../instrument_drivers/Lakeshore/Model_325.py | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index 58258a557aa..a1bad1b5bbc 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -1,6 +1,7 @@ import numpy as np from typing import cast, Union, List, Tuple, Iterable from itertools import takewhile, repeat +import os from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum, Numbers @@ -39,25 +40,47 @@ def strip(strings: Iterable[str]) -> Tuple: return tuple(s.strip() for s in strings) with open(file_path, "r") as curve_file: - file_content = curve_file.read() + lines = iter(curve_file.readlines()) - lines = iter(file_content.split("\n")) # Meta data lines contain a colon metadata_lines = takewhile(lambda s: ":" in s, lines) - curve_data = dict([strip(line.split(":")) for line in metadata_lines]) + # Data from the file is collected in the following dict + file_data = dict([strip(line.split(":")) for line in metadata_lines]) # After meta data we have a data header header_items = strip(split_data_line(next(lines))) # After that we have the curve data data = [ split_data_line(line, parsers=float) - for line in lines if line != "" + for line in lines if line.strip() != "" ] - curve_data["data"] = dict( + file_data["data"] = dict( zip(header_items, zip(*data)) ) - return curve_data + return file_data + + +def sanitize_data(file_data: dict) -> None: + """ + Data as found in the curve files are slightly different then + the dictionary as expected by the 'upload_curve' method of the + driver + + Note: This function modifies the input + """ + data_dict = file_data["data"] + # We do not need the index column + del data_dict["No."] + # Rename the 'Units' column to the appropriate name + # Look up under the 'Data Format' entry to find what units we have + data_format = file_data['Data Format'] + # This is a string in the form '4 (Log Ohms/Kelvin)' + data_format_int = int(data_format[0]) + correct_name = Model_325_Curve.valid_sensor_units[data_format_int - 1] + # Rename the column + data_dict[correct_name] = data_dict["Units"] + del data_dict["Units"] class Model_325_Curve(InstrumentChannel): @@ -186,7 +209,7 @@ def set_data(self, data_dict: dict, sensor_unit: str=None) ->None: enumerate(zip(temperature_values, sensor_values)): cmd_str = f"CRVPT {self._index}, {value_index + 1}, " \ - f"{sensor_value:3.3}, {temperature_value:3.3}" + f"{sensor_value:3.3f}, {temperature_value:3.3f}" self.write(cmd_str) @@ -523,8 +546,26 @@ def upload_curve( sensor_unit = Model_325_Curve.validate_datadict(data_dict) - curve = self.curve[index] + curve = self.curve[index - 1] curve.curve_name(name) curve.serial_number(serial_number) curve.format(f"{sensor_unit}/K") curve.set_data(data_dict, sensor_unit=sensor_unit) + + def upload_curve_from_file(self, index: int, file_path: str) -> None: + """ + Upload a curve from a curve file. Note that we only support + curve files with extension *.330 + """ + _, filename = os.path.split(file_path) + if not filename.endswith(".330"): + raise ValueError("Only curve files with extension *.330 is supported") + + file_data = read_curve_file(file_path) + sanitize_data(file_data) + + name = file_data["Sensor Model"] + serial_number = file_data["Serial Number"] + data_dict = file_data["data"] + + self.upload_curve(index, name, serial_number, data_dict) From 1cb3553712b1f468811fe89ec67c2c6bb41508b0 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Wed, 19 Dec 2018 19:11:23 -0800 Subject: [PATCH 403/719] get rid of superfluous newline --- qcodes/instrument_drivers/Lakeshore/Model_325.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index a1bad1b5bbc..adbe6130b3e 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -31,7 +31,6 @@ def split_data_line( parsers = repeat(parsers) line_split = [i for i in line.split(" ") if i != ""] - return [ parser(i) for parser, i in zip(parsers, line_split) ] From 67374fa51587f162ada51b919b862d12fc9e54ed Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 20 Dec 2018 12:30:06 +0100 Subject: [PATCH 404/719] S46 pass with strict optional --- qcodes/instrument_drivers/tektronix/Keithley_s46.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/tektronix/Keithley_s46.py b/qcodes/instrument_drivers/tektronix/Keithley_s46.py index 3a91064ab08..9ec6c246739 100644 --- a/qcodes/instrument_drivers/tektronix/Keithley_s46.py +++ b/qcodes/instrument_drivers/tektronix/Keithley_s46.py @@ -25,7 +25,7 @@ class RelayLock: """ def __init__(self, relay_name: str): self.relay_name = relay_name - self._locked_by: int = None + self._locked_by: Optional[int] = None def acquire(self, channel_number: int) -> None: """ @@ -101,6 +101,9 @@ def _set(self, new_state) -> None: elif new_state == "open": self._lock.release(self._channel_number) + if self._instrument is None: + raise RuntimeError("Cannot set the value on a parameter " + "that is not attached to an instrument.") self._instrument.write(f":{new_state} (@{self._channel_number})") @property From 83f83ee31ac81b6986450669d5d9e3a7475ca6c3 Mon Sep 17 00:00:00 2001 From: Mikhail Astafev Date: Thu, 20 Dec 2018 13:50:30 +0100 Subject: [PATCH 405/719] Fix pep8 and other style stuff --- .../oxford/MercuryiPS_VISA.py | 17 +++--- qcodes/math/field_vector.py | 56 +++++++++---------- qcodes/tests/drivers/test_MercuryiPS.py | 10 ++-- qcodes/tests/test_field_vector.py | 48 +++++++++------- qcodes/utils/helpers.py | 4 +- 5 files changed, 73 insertions(+), 62 deletions(-) diff --git a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py index c2a3b421068..f2f4036513c 100644 --- a/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py +++ b/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py @@ -202,8 +202,8 @@ def _param_setter(self, set_cmd: str, value: Union[float, str]) -> None: # holds the value reported back by the instrument self._parent.ask(dressed_cmd) - # TODO: we could use the opportunity to check that we did set/ achieve - # the intended value + # TODO: we could use the opportunity to check that we did set/achieve + # the intended value class MercuryiPS(VisaInstrument): @@ -264,8 +264,9 @@ def __init__(self, name: str, address: str, visalib=None, y=self.GRPY.field(), z=self.GRPZ.field()) - for coord, unit in zip(['x', 'y', 'z', 'r', 'theta', 'phi', 'rho'], - ['T', 'T', 'T', 'T', 'degrees', 'degrees', 'T']): + for coord, unit in zip( + ['x', 'y', 'z', 'r', 'theta', 'phi', 'rho'], + ['T', 'T', 'T', 'T', 'degrees', 'degrees', 'T']): self.add_parameter(name=f'{coord}_target', label=f'{coord.upper()} target field', unit=unit, @@ -278,11 +279,13 @@ def __init__(self, name: str, address: str, visalib=None, get_cmd=partial(self._get_measured, [coord])) # FieldVector-valued parameters # + self.add_parameter(name="field_target", label="target field", unit="T", get_cmd=self._get_target_field, set_cmd=self._set_target_field) + self.add_parameter(name="field_measured", label="measured field", unit="T", @@ -314,7 +317,7 @@ def _get_ramp_rate(self) -> FieldVector: z=self.GRPZ.field_ramp_rate(), ) - def _set_ramp_rate(self, rate : FieldVector) -> None: + def _set_ramp_rate(self, rate: FieldVector) -> None: self.GRPX.field_ramp_rate(rate.x) self.GRPY.field_ramp_rate(rate.y) self.GRPZ.field_ramp_rate(rate.z) @@ -363,7 +366,7 @@ def _set_target(self, coordinate: str, target: float) -> None: for targ, slave in zip(cartesian_targ, self.submodules.values()): slave.field_target(targ) - def _set_target_field(self, field : FieldVector) -> None: + def _set_target_field(self, field: FieldVector) -> None: for coord in 'xyz': self._set_target(coord, field[coord]) @@ -439,7 +442,7 @@ def set_new_field_limits(self, limit_func: Callable) -> None: self._field_limits = limit_func - def ramp(self, mode : str = "safe") -> None: + def ramp(self, mode: str="safe") -> None: """ Ramp the fields to their present target value diff --git a/qcodes/math/field_vector.py b/qcodes/math/field_vector.py index c7c4f21c40f..ab4045c23fb 100644 --- a/qcodes/math/field_vector.py +++ b/qcodes/math/field_vector.py @@ -59,7 +59,6 @@ def __init__(self, x=None, y=None, z=None, r=None, theta=None, phi=None, self._compute_unknowns() def _set_attribute_value(self, attr_name, value): - if value is None: return @@ -75,17 +74,15 @@ def _set_attribute_value(self, attr_name, value): ) def _set_attribute_values(self, attr_names, values): - for attr_name, value in zip(attr_names, values): self._set_attribute_value(attr_name, value) def __getnewargs__(self): - return (self.x, self.y, self.z) + return self.x, self.y, self.z @staticmethod def _cartesian_to_other(x, y, z): """ Convert a cartesian set of coordinates to values of interest.""" - if any([i is None for i in [x, y, z]]): return None @@ -102,7 +99,6 @@ def _cartesian_to_other(x, y, z): @staticmethod def _spherical_to_other(r, theta, phi): """Convert from spherical to other representations""" - if any([i is None for i in [r, theta, phi]]): return None @@ -116,7 +112,6 @@ def _spherical_to_other(r, theta, phi): @staticmethod def _cylindrical_to_other(phi, rho, z): """Convert from cylindrical to other representations""" - if any([i is None for i in [phi, rho, z]]): return None @@ -139,7 +134,6 @@ def _compute_unknowns(self): This function will raise an error if there are contradictory inputs (e.g. x=3, y=4, z=0 and rho=6). """ - for f in [ lambda: FieldVector._cartesian_to_other(self._x, self._y, self._z), lambda: FieldVector._spherical_to_other(self._r, self._theta, @@ -153,7 +147,7 @@ def _compute_unknowns(self): self._set_attribute_values(FieldVector.attributes, new_values) break - def copy(self : T, other : T): + def copy(self: T, other: T): """Copy the properties of other vector to yourself""" for att in FieldVector.attributes: value = getattr(other, "_" + att) @@ -167,12 +161,14 @@ def set_vector(self, **new_values): >>> f = FieldVector(x=0, y=2, z=6) >>> f.set_vector(x=9, y=3, z=1) >>> f.set_vector(r=1, theta=30.0, phi=10.0) - >>> f.set_vector(x=9, y=0) # this should raise a value error: + # The following should raise a value error: # "Can only set vector with a complete value set" - >>> f.set_vector(x=9, y=0, r=3) # although mathematically it is - # possible to compute the complete vector from the values given, - # this is too hard to implement with generality (and not worth it) - # so this to will raise the above mentioned ValueError + >>> f.set_vector(x=9, y=0) + # Although mathematically it is possible to compute the complete + # vector from the values given, this is too hard to implement with + # generality (and not worth it), so the following will raise the + # above-mentioned ValueError too + >>> f.set_vector(x=9, y=0, r=3) """ names = sorted(list(new_values.keys())) groups = [["x", "y", "z"], ["phi", "r", "theta"], ["phi", "rho", "z"]] @@ -191,18 +187,18 @@ def set_component(self, **new_values): Examples: >>> f = FieldVector(x=2, y=3, z=4) - >>> f.set_component(r=10) # Since r is part of the set - # (r, theta, phi) representing spherical coordinates, setting r - # means that theta and phi are kept constant and only r is changed. - # After changing r, (x, y, z) values are recomputed, as is the rho - # coordinate. Internally we arrange this by setting x, y, z and - # rho to None and calling self._compute_unknowns() + # Since r is part of the set (r, theta, phi) representing + # spherical coordinates, setting r means that theta and phi are + # kept constant and only r is changed. After changing r, + # (x, y, z) values are recomputed, as is the rho coordinate. + # Internally we arrange this by setting x, y, z and rho to None + # and calling self._compute_unknowns() + >>> f.set_component(r=10) Parameters: new_values (dict): keys representing parameter names and values the values to be set """ - if len(new_values) > 1: raise NotImplementedError("Cannot set multiple components at once") @@ -302,14 +298,18 @@ def __sub__(self, other): # NB: we disable the pylint warning here so that we can match # NumPy's naming convention for the norm method. - def norm(self, ord : NormOrder = 2) -> float: # pylint: disable=redefined-builtin + def norm(self, + ord: NormOrder=2 # pylint: disable=redefined-builtin + ) -> float: """ Returns the norm of this field vector. See np.norm for the definition of the ord keyword argument. """ return np.linalg.norm([self.x, self.y, self.z], ord=ord) - def distance(self, other, ord : NormOrder = 2) -> float: # pylint: disable=redefined-builtin + def distance(self, other, + ord: NormOrder=2 # pylint: disable=redefined-builtin + ) -> float: return (self - other).norm(ord=ord) @property @@ -340,7 +340,7 @@ def r(self) -> float: def phi(self) -> float: return np.degrees(self._phi) - ## Representation Methods ## + # Representation Methods # def repr_cartesian(self) -> str: return f"FieldVector(x={self.x}, y={self.y}, z={self.z})" @@ -361,22 +361,22 @@ def __repr__(self) -> str: else: return super().__repr__() - ## Homogenous Coordinates ## + # Homogeneous Coordinates # def as_homogeneous(self) -> np.ndarray: return np.array([self.x, self.y, self.z, 1]) @classmethod - def from_homogeneous(cls : Type[T], hvec : np.ndarray) -> T: - # Homogenous coordinates define an equivalence relation + def from_homogeneous(cls: Type[T], hvec: np.ndarray) -> T: + # Homogeneous coordinates define an equivalence relation # [x / s, y / s, z / s, 1] == [x, y, z, s]. # More generally, # [x, y, z, s] == [x', y', z', s'] # iff x / s == x' / s', # y / s == y' / s', and # z / s == z' / s'. - # This definition has the consequence that for any - # w, w * [x, y, z, s] == [x, y, z, s]. + # This definition has the consequence that for any w, + # w * [x, y, z, s] == [x, y, z, s]. # Thus, we start by rescaling such that s == 1. hvec /= hvec[-1] return cls( diff --git a/qcodes/tests/drivers/test_MercuryiPS.py b/qcodes/tests/drivers/test_MercuryiPS.py index 09649f3f9f8..61a6f8ba6fc 100644 --- a/qcodes/tests/drivers/test_MercuryiPS.py +++ b/qcodes/tests/drivers/test_MercuryiPS.py @@ -13,7 +13,6 @@ @pytest.fixture(scope='function') def driver(): - mips = MercuryiPS('mips', address='GPIB::1::INSTR', visalib=visalib) yield mips @@ -84,11 +83,9 @@ def test_vector_ramp_rate(driver): def test_wrong_field_limit_raises(): - # check that a non-callable input fails with pytest.raises(ValueError): - MercuryiPS('mips', address='GPIB::1::INSTR', - visalib=visalib, + MercuryiPS('mips', address='GPIB::1::INSTR', visalib=visalib, field_limits=0) @@ -102,7 +99,7 @@ def test_field_limits(x, y, z, driver_spher_lim, driver_cyl_lim): """ # TODO: there really isn't a reason to do this tuple-by-tuple - # and not point-by-point. Extend the test to do that. + # and not point-by-point. Extend the test to do that. for mip in [driver_spher_lim, driver_cyl_lim]: # reset (PyVISA-sim unfortunately has memory) @@ -151,7 +148,8 @@ def test_ramp_safely(driver, x, y, z, caplog): # Use the FieldVector interface here to increase coverage. driver.field_target(FieldVector(x=x, y=y, z=z)) - exp_order = np.array(['x', 'y', 'z'])[np.argsort(np.abs(np.array([x, y, z])))] + exp_order = \ + np.array(['x', 'y', 'z'])[np.argsort(np.abs(np.array([x, y, z])))] with caplog.at_level(logging.DEBUG, logger='qcodes.instrument.visa'): caplog.clear() diff --git a/qcodes/tests/test_field_vector.py b/qcodes/tests/test_field_vector.py index f41650c99bd..b80847e2a51 100644 --- a/qcodes/tests/test_field_vector.py +++ b/qcodes/tests/test_field_vector.py @@ -1,6 +1,6 @@ """ -Test properties of the coordinate transforms in the field vector module to test if everything has been correctly -implemented. +Test properties of the coordinate transforms in the field vector module to +test if everything has been correctly implemented. """ import numpy as np import json @@ -15,17 +15,17 @@ "cartesian": tuples( floats(min_value=0, max_value=1), # x floats(min_value=0, max_value=1), # y - floats(min_value=0, max_value=1) # z + floats(min_value=0, max_value=1) # z ), "spherical": tuples( - floats(min_value=0, max_value=1), # r + floats(min_value=0, max_value=1), # r floats(min_value=0, max_value=180), # theta - floats(min_value=0, max_value=180) # phi + floats(min_value=0, max_value=180) # phi ), "cylindrical": tuples( - floats(min_value=0, max_value=1), # rho + floats(min_value=0, max_value=1), # rho floats(min_value=0, max_value=180), # phi - floats(min_value=0, max_value=1) # z + floats(min_value=0, max_value=1) # z ) } @@ -34,33 +34,38 @@ @settings(max_examples=10) def test_spherical_properties(spherical0): """ - If the cartesian to spherical transform has been correctly implemented then we expect certain symmetrical properties + If the cartesian to spherical transform has been correctly implemented + then we expect certain symmetrical properties """ # Generate a random coordinate in spherical representation spherical0 = dict(zip(["r", "theta", "phi"], spherical0)) cartisian0 = FieldVector(**spherical0).get_components("x", "y", "z") - # Mirror the theta angle in the xy-plane. This should flip the sign of the z-coordinate + # Mirror the theta angle in the xy-plane. + # This should flip the sign of the z-coordinate spherical1 = dict(spherical0) spherical1["theta"] = 180 - spherical0["theta"] cartisian1 = FieldVector(**spherical1).get_components("x", "y", "z") assert np.allclose(cartisian0, cartisian1 * np.array([1, 1, -1])) - # Add 180 to the phi coordinate. This should flip the sign of the xy coordinate + # Add 180 to the phi coordinate. + # This should flip the sign of the xy coordinate spherical2 = dict(spherical0) spherical2["phi"] = 180 + spherical0["phi"] cartisian2 = FieldVector(**spherical2).get_components("x", "y", "z") assert np.allclose(cartisian0, cartisian2 * np.array([-1, -1, 1])) - # Mirroring the theta angle in the xy-plane and adding 180 to the phi coordinate should flip all cartesian - # coordinates + # Mirroring the theta angle in the xy-plane + # and adding 180 to the phi coordinate + # should flip all cartesian coordinates spherical3 = dict(spherical0) - spherical3["theta"] = 180 - spherical0["theta"] # This should only flip the z-coordinate - spherical3["phi"] = 180 + spherical0["phi"] # This should flip the xy-coordinate + spherical3["theta"] = 180 - spherical0["theta"] # should only flip z + spherical3["phi"] = 180 + spherical0["phi"] # should flip xy cartisian3 = FieldVector(**spherical3).get_components("x", "y", "z") assert np.allclose(cartisian0, cartisian3 * np.array([-1, -1, -1])) - # Finally flipping the sign of the r coordinate should flip all cartesian coordinates + # Finally, flipping the sign of the r coordinate + # should flip all cartesian coordinates spherical4 = dict(spherical0) spherical4["r"] = -spherical0["r"] # This should flip all coordinates cartisian4 = FieldVector(**spherical4).get_components("x", "y", "z") @@ -71,8 +76,8 @@ def test_spherical_properties(spherical0): @settings(max_examples=10) def test_cylindrical_properties(cylindrical0): """ - If the cartesian to cylindrical transform has been correctly implemented then we expect certain symmetrical - properties + If the cartesian to cylindrical transform has been correctly implemented + then we expect certain symmetrical properties """ # Generate a random coordinate in cylindrical representation cylindrical0 = dict(zip(["rho", "phi", "z"], cylindrical0)) @@ -85,6 +90,7 @@ def test_cylindrical_properties(cylindrical0): assert np.allclose(cartisian0, cartisian1 * np.array([-1, -1, 1])) + @given( random_coordinates["cylindrical"], random_coordinates["spherical"] @@ -94,8 +100,11 @@ def test_triangle_inequality(cylindrical0, spherical0): cylindrical0 = FieldVector(**dict(zip(["rho", "phi", "z"], cylindrical0))) spherical0 = FieldVector(**dict(zip(["r", "phi", "theta"], spherical0))) - assert (cylindrical0 + spherical0).norm() <= (cylindrical0.norm() + spherical0.norm()) - assert cylindrical0.distance(spherical0) <= (cylindrical0.norm() + spherical0.norm()) + assert (cylindrical0 + spherical0).norm() \ + <= (cylindrical0.norm() + spherical0.norm()) + assert cylindrical0.distance(spherical0) \ + <= (cylindrical0.norm() + spherical0.norm()) + @given(random_coordinates["cartesian"]) @settings(max_examples=10) @@ -108,6 +117,7 @@ def test_homogeneous_roundtrip(cartesian0): FieldVector.from_homogeneous(h_vec).get_components(*"xyz") ) + @given(random_coordinates["spherical"]) @settings(max_examples=10) def test_json_dump(spherical0): diff --git a/qcodes/utils/helpers.py b/qcodes/utils/helpers.py index 4c55395fe8a..cc6949ad888 100644 --- a/qcodes/utils/helpers.py +++ b/qcodes/utils/helpers.py @@ -46,8 +46,8 @@ def default(self, obj): "__dtype__" containing value "complex" * object with a `_JSONEncoder` method get converted the return value of that method - * objects which support the pickle protocol get converted using the data - provided by that protocol + * objects which support the pickle protocol get converted using the + data provided by that protocol * other objects which cannot be serialized get converted to their string representation (suing the `str` function) """ From 3b8f9b120afb58b1764a517045f7faa4d598e346 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 20 Dec 2018 14:47:24 +0100 Subject: [PATCH 406/719] Add typing to monitor --- qcodes/monitor/monitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/monitor/monitor.py b/qcodes/monitor/monitor.py index bfb96eed8d9..25236da5033 100644 --- a/qcodes/monitor/monitor.py +++ b/qcodes/monitor/monitor.py @@ -26,7 +26,7 @@ import time import json from contextlib import suppress -from typing import Dict, Any +from typing import Dict, Any, Optional, Union from collections import defaultdict import asyncio @@ -56,7 +56,7 @@ def _get_metadata(*parameters) -> Dict[str, Any]: metas = defaultdict(list) # type: dict for parameter in parameters: # Get the latest value from the parameter, respecting the max_val_age parameter - meta = {} + meta: Dict[str, Optional[str]] = {} meta["value"] = str(parameter.get_latest()) if parameter.get_latest.get_timestamp() is not None: meta["ts"] = parameter.get_latest.get_timestamp().timestamp() From 03e982a38de7ac6e7503fcd8d2c32a7cd28a76da Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 20 Dec 2018 16:35:21 +0100 Subject: [PATCH 407/719] Allow this to be None to match signature of caller --- qcodes/dataset/database_extract_runs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qcodes/dataset/database_extract_runs.py b/qcodes/dataset/database_extract_runs.py index 1fe782c6c1e..50be33cea37 100644 --- a/qcodes/dataset/database_extract_runs.py +++ b/qcodes/dataset/database_extract_runs.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Union, Optional from warnings import warn import os @@ -244,7 +244,7 @@ def _populate_results_table(source_conn: ConnectionPlus, def _rewrite_timestamps(target_conn: ConnectionPlus, target_run_id: int, correct_run_timestamp: float, - correct_completed_timestamp: float) -> None: + correct_completed_timestamp: Optional[float]) -> None: """ Update the timestamp to match the original one """ From 345846edcf8aba7fa6b06dfc6368a7f95d8d9d50 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 20 Dec 2018 17:13:26 +0100 Subject: [PATCH 408/719] Handle potential missing config and schema --- qcodes/config/config.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qcodes/config/config.py b/qcodes/config/config.py index 8f323ad8687..09581e99098 100644 --- a/qcodes/config/config.py +++ b/qcodes/config/config.py @@ -366,8 +366,14 @@ def describe(self, name: str) -> str: e.g. name="user.scriptfolder" """ val = self.current_config + if val is None: + raise RuntimeError(f"Config is empty, cannot describe entry.") + if self.current_schema is None: + raise RuntimeError("No schema found, cannot describe entry.") sch = self.current_schema["properties"] for key in name.split('.'): + if val is None: + raise RuntimeError(f"{name} is not found in config") val = val[key] if sch.get(key): sch = sch[key] From f28b48a39175b406cb117b04a1da13b3deb8db38 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 20 Dec 2018 17:23:29 +0100 Subject: [PATCH 409/719] Cast raw values since these are not actually None --- .../QuantumDesign/DynaCoolPPMS/DynaCool.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py b/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py index 7359307ef00..517f76408e1 100644 --- a/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py +++ b/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py @@ -217,11 +217,12 @@ def _field_setter(self, param: str, value: float) -> None: The combined set function for the three field parameters, field_setpoint, field_rate, and field_approach """ - vals: List[Union[int, float]] - vals = list(self.parameters[p].raw_value for p in self.field_params) - vals[self.field_params.index(param)] = value + temp_values = list(self.parameters[p].raw_value + for p in self.field_params) + values = cast(List[Union[int, float]], temp_values) + values[self.field_params.index(param)] = value - self.write(f'FELD {vals[0]}, {vals[1]}, {vals[2]}, 0') + self.write(f'FELD {values[0]}, {values[1]}, {values[2]}, 0') def _temp_getter(self, param_name: str) -> Union[int, float]: """ @@ -240,11 +241,12 @@ def _temp_setter(self, param: str, value: float) -> None: The setter function for the temperature parameters. All three are set with the same call to the instrument API """ - vals: List[Union[int, float]] - vals = list(self.parameters[par].raw_value for par in self.temp_params) - vals[self.temp_params.index(param)] = value + temp_values = list(self.parameters[par].raw_value + for par in self.temp_params) + values = cast(List[Union[int, float]], temp_values) + values[self.temp_params.index(param)] = value - self.write(f'TEMP {vals[0]}, {vals[1]}, {vals[2]}') + self.write(f'TEMP {values[0]}, {values[1]}, {values[2]}') def write(self, cmd: str) -> None: """ From 7ef1dec39ec6cdf4707a1d5fad731547a6e70da3 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 20 Dec 2018 18:15:46 -0800 Subject: [PATCH 410/719] 1) Processed PR comments 2) Added file parser test --- .../instrument_drivers/Lakeshore/Model_325.py | 52 +++++++---------- .../drivers/test_lakeshore_file_parser.py | 58 +++++++++++++++++++ 2 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 qcodes/tests/drivers/test_lakeshore_file_parser.py diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index adbe6130b3e..c47aea2b199 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -1,6 +1,6 @@ import numpy as np -from typing import cast, Union, List, Tuple, Iterable -from itertools import takewhile, repeat +from typing import cast, List, Tuple, Iterable, TextIO +from itertools import takewhile import os from qcodes import VisaInstrument, InstrumentChannel, ChannelList @@ -8,7 +8,7 @@ from qcodes.instrument.group_parameter import GroupParameter, Group -def read_curve_file(file_path: str) -> dict: +def read_curve_file(curve_file: TextIO) -> dict: """ Read a curve file with extension *.330 The format of the file is as follows: @@ -22,34 +22,24 @@ def read_curve_file(file_path: str) -> dict: data21 data22 data23 """ - def split_data_line( - line: str, - parsers: Union[type, List]=str - ) -> List[str]: - - if not isinstance(parsers, list): - parsers = repeat(parsers) - - line_split = [i for i in line.split(" ") if i != ""] - return [ - parser(i) for parser, i in zip(parsers, line_split) - ] + def split_data_line(line: str, parser: type = str) -> List[str]: + return [parser(i) for i in line.split(" ") if i != ""] def strip(strings: Iterable[str]) -> Tuple: return tuple(s.strip() for s in strings) - with open(file_path, "r") as curve_file: - lines = iter(curve_file.readlines()) - + lines = iter(curve_file.readlines()) # Meta data lines contain a colon metadata_lines = takewhile(lambda s: ":" in s, lines) # Data from the file is collected in the following dict - file_data = dict([strip(line.split(":")) for line in metadata_lines]) + file_data = dict(metadata={}, data={}) + # Capture meta data + file_data["metadata"] = dict([strip(line.split(":")) for line in metadata_lines]) # After meta data we have a data header header_items = strip(split_data_line(next(lines))) # After that we have the curve data data = [ - split_data_line(line, parsers=float) + split_data_line(line, parser=float) for line in lines if line.strip() != "" ] @@ -60,27 +50,27 @@ def strip(strings: Iterable[str]) -> Tuple: return file_data -def sanitize_data(file_data: dict) -> None: +def get_sanitize_data(file_data: dict) -> dict: """ Data as found in the curve files are slightly different then the dictionary as expected by the 'upload_curve' method of the driver - - Note: This function modifies the input """ - data_dict = file_data["data"] + data_dict = dict(file_data["data"]) # We do not need the index column del data_dict["No."] # Rename the 'Units' column to the appropriate name # Look up under the 'Data Format' entry to find what units we have - data_format = file_data['Data Format'] + data_format = file_data['metadata']['Data Format'] # This is a string in the form '4 (Log Ohms/Kelvin)' - data_format_int = int(data_format[0]) + data_format_int = int(data_format.split()[0]) correct_name = Model_325_Curve.valid_sensor_units[data_format_int - 1] # Rename the column data_dict[correct_name] = data_dict["Units"] del data_dict["Units"] + return data_dict + class Model_325_Curve(InstrumentChannel): @@ -560,11 +550,11 @@ def upload_curve_from_file(self, index: int, file_path: str) -> None: if not filename.endswith(".330"): raise ValueError("Only curve files with extension *.330 is supported") - file_data = read_curve_file(file_path) - sanitize_data(file_data) + with open(file_path, "r") as curve_file: + file_data = read_curve_file(curve_file) - name = file_data["Sensor Model"] - serial_number = file_data["Serial Number"] - data_dict = file_data["data"] + data_dict = get_sanitize_data(file_data) + name = file_data["metadata"]["Sensor Model"] + serial_number = file_data["metadata"]["Serial Number"] self.upload_curve(index, name, serial_number, data_dict) diff --git a/qcodes/tests/drivers/test_lakeshore_file_parser.py b/qcodes/tests/drivers/test_lakeshore_file_parser.py new file mode 100644 index 00000000000..74897ee6991 --- /dev/null +++ b/qcodes/tests/drivers/test_lakeshore_file_parser.py @@ -0,0 +1,58 @@ +import io +import pytest + +from qcodes.instrument_drivers.Lakeshore.Model_325 import read_curve_file, get_sanitize_data + +curve_file_content = """Sensor Model: CX-1050-SD-HT-1.4L +Serial Number: X116121 +Interpolation Method: Lagrangian +SetPoint Limit: 325.0 (Kelvin) +Data Format: 4 (Log Ohms/Kelvin) +Number of Breakpoints: 52 + +No. Units Temperature (K) + + 1 1.70333 325.0 + 2 1.70444 324.0 + 3 1.72168 309.0 + 4 1.73995 294.0 + 5 1.75936 279.0 + 6 1.78000 264.0 +""" + + +@pytest.fixture(scope="function") +def curve_file(): + yield io.StringIO(curve_file_content) + + +def test_file_parser(curve_file): + file_data = read_curve_file(curve_file) + + assert list(file_data.keys()) == ["metadata", "data"] + + assert file_data["metadata"] == { + "Sensor Model": "CX-1050-SD-HT-1.4L", + "Serial Number": "X116121", + "Interpolation Method": "Lagrangian", + "SetPoint Limit": "325.0 (Kelvin)", + "Data Format": "4 (Log Ohms/Kelvin)", + "Number of Breakpoints": "52" + } + + assert file_data["data"] == { + "No.": (1.0, 2.0, 3.0, 4.0, 5.0, 6.0), + "Units": (1.70333, 1.70444, 1.72168, 1.73995, 1.75936, 1.78), + "Temperature (K)": (325.0, 324.0, 309.0, 294.0, 279.0, 264.0) + } + + +def test_sanitise_data(curve_file): + + file_data = read_curve_file(curve_file) + data_dict = get_sanitize_data(file_data) + + assert data_dict == { + "log Ohm": (1.70333, 1.70444, 1.72168, 1.73995, 1.75936, 1.78), + "Temperature (K)": (325.0, 324.0, 309.0, 294.0, 279.0, 264.0) + } From 29dc926df0622aa8c74b7b357757b73a95243cd2 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 20 Dec 2018 18:23:42 -0800 Subject: [PATCH 411/719] Better docstrings --- qcodes/instrument_drivers/Lakeshore/Model_325.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index c47aea2b199..e230651b129 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -11,15 +11,12 @@ def read_curve_file(curve_file: TextIO) -> dict: """ Read a curve file with extension *.330 - The format of the file is as follows: + The file format of this file is shown in qcodes\tests\drivers\test_lakeshore_file_parser.py - Item1: value - Item2: value - Item3: value - - Header1 Header2 Header3 - data11 data12 data13 - data21 data22 data23 + The output is a dictionary with keys: "metadata" and "data". + The metadata dictionary contains the first n lines of the curve file which + are in the format "item: value". The data dictionary contains the actual + curve data. """ def split_data_line(line: str, parser: type = str) -> List[str]: @@ -546,8 +543,7 @@ def upload_curve_from_file(self, index: int, file_path: str) -> None: Upload a curve from a curve file. Note that we only support curve files with extension *.330 """ - _, filename = os.path.split(file_path) - if not filename.endswith(".330"): + if not file_path.endswith(".330"): raise ValueError("Only curve files with extension *.330 is supported") with open(file_path, "r") as curve_file: From 6ec1c687e26bc5b6a9f2d7dbcde3a888d56cf7d0 Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 20 Dec 2018 18:41:24 -0800 Subject: [PATCH 412/719] Mypy passing --- qcodes/instrument_drivers/Lakeshore/Model_325.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index e230651b129..957f4ff3f63 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -1,7 +1,6 @@ import numpy as np from typing import cast, List, Tuple, Iterable, TextIO from itertools import takewhile -import os from qcodes import VisaInstrument, InstrumentChannel, ChannelList from qcodes.utils.validators import Enum, Numbers @@ -11,7 +10,8 @@ def read_curve_file(curve_file: TextIO) -> dict: """ Read a curve file with extension *.330 - The file format of this file is shown in qcodes\tests\drivers\test_lakeshore_file_parser.py + The file format of this file is shown in test_lakeshore_file_parser.py + in the test module The output is a dictionary with keys: "metadata" and "data". The metadata dictionary contains the first n lines of the curve file which @@ -29,9 +29,10 @@ def strip(strings: Iterable[str]) -> Tuple: # Meta data lines contain a colon metadata_lines = takewhile(lambda s: ":" in s, lines) # Data from the file is collected in the following dict - file_data = dict(metadata={}, data={}) + file_data: dict = dict(metadata={}, data={}) # Capture meta data - file_data["metadata"] = dict([strip(line.split(":")) for line in metadata_lines]) + parsed_lines = [strip(line.split(":")) for line in metadata_lines] + file_data["metadata"] = {key: value for key, value in parsed_lines} # After meta data we have a data header header_items = strip(split_data_line(next(lines))) # After that we have the curve data From c124bd09099277242044c8c9d64bd1a0150854fc Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 20 Dec 2018 18:43:09 -0800 Subject: [PATCH 413/719] Mypy passing --- qcodes/instrument_drivers/Lakeshore/Model_325.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index 957f4ff3f63..c31ecd08337 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -29,7 +29,7 @@ def strip(strings: Iterable[str]) -> Tuple: # Meta data lines contain a colon metadata_lines = takewhile(lambda s: ":" in s, lines) # Data from the file is collected in the following dict - file_data: dict = dict(metadata={}, data={}) + file_data = dict() # Capture meta data parsed_lines = [strip(line.split(":")) for line in metadata_lines] file_data["metadata"] = {key: value for key, value in parsed_lines} From ac7c19263ccf326347f2d421d00ff2aa892fc13e Mon Sep 17 00:00:00 2001 From: sochatoo Date: Thu, 20 Dec 2018 18:45:47 -0800 Subject: [PATCH 414/719] fix grammar mistake in exception message --- qcodes/instrument_drivers/Lakeshore/Model_325.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/instrument_drivers/Lakeshore/Model_325.py b/qcodes/instrument_drivers/Lakeshore/Model_325.py index c31ecd08337..4d74634bdb5 100644 --- a/qcodes/instrument_drivers/Lakeshore/Model_325.py +++ b/qcodes/instrument_drivers/Lakeshore/Model_325.py @@ -545,7 +545,7 @@ def upload_curve_from_file(self, index: int, file_path: str) -> None: curve files with extension *.330 """ if not file_path.endswith(".330"): - raise ValueError("Only curve files with extension *.330 is supported") + raise ValueError("Only curve files with extension *.330 are supported") with open(file_path, "r") as curve_file: file_data = read_curve_file(curve_file) From b597a6490f19db409077e9ed6a142bdd51ad301e Mon Sep 17 00:00:00 2001 From: Thibaud Ruelle Date: Fri, 21 Dec 2018 07:25:23 +0100 Subject: [PATCH 415/719] feat: add specs for model '33512B' --- qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py index 3ef0e300626..56ef0ad18bb 100644 --- a/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py +++ b/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py @@ -298,12 +298,14 @@ def __init__(self, name, address, silent=False, **kwargs): no_of_channels = {'33210A': 1, '33250A': 1, '33511B': 1, + '33512B': 2, '33522B': 2, '33622A': 2 } self._max_freqs = {'33210A': 10e6, '33511B': 20e6, + '33512B': 20e6, '33250A': 80e6, '33522B': 30e6, '33622A': 120e6} From 251b9d234c8f909118384eadf8b88972523fd7c9 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Thu, 6 Dec 2018 15:22:12 +0100 Subject: [PATCH 416/719] Add function to export data as pandas array --- qcodes/dataset/data_set.py | 54 +++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index b788ba51b12..072b7439e6a 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -8,6 +8,7 @@ import uuid from queue import Queue, Empty import numpy +import pandas as pd from qcodes.dataset.param_spec import ParamSpec from qcodes.instrument.parameter import _BaseParameter @@ -813,7 +814,7 @@ def get_parameter_data( """ Returns the values stored in the DataSet for the specified parameters and their dependencies. If no paramerers are supplied the values will - be returned for all parameters that are not them self depdendencies. + be returned for all parameters that are not them self dependencies. The values are returned as a dictionary with names of the requested parameters as keys and values consisting of dictionaries with the @@ -851,6 +852,57 @@ def get_parameter_data( return get_parameter_data(self.conn, self.table_name, valid_param_names, start, end) + def get_data_as_pandas_dataframe(self, + *params: Union[str, + ParamSpec, + _BaseParameter], + start: Optional[int] = None, + end: Optional[int] = None) -> \ + List[pd.DataFrame]: + """ + Returns the values stored in the DataSet for the specified parameters + and their dependencies. If no paramerers are supplied the values will + be returned for all parameters that are not them self dependencies. + + The values are returned as a list of Pandas DataFrames. One for each + names of the parameters and its dependencies as keys and numpy arrays + of the data as values. If some of the parameters are stored as + arrays the remaining parameters are expanded to the same shape as these. + Apart from this expansion the data returned by this method + is the transpose of the date returned by `get_data`. + + If provided, the start and end arguments select a range of results + by result count (index). If the range is empty - that is, if the end is + less than or equal to the start, or if start is after the current end + of the DataSet – then a list of empty arrays is returned. + + Args: + *params: string parameter names, QCoDeS Parameter objects, and + ParamSpec objects. If no parameters are supplied data for + all parameters that are not a dependency of another + parameter will be returned. + start: start value of selection range (by result count); ignored + if None + end: end value of selection range (by results count); ignored if + None + + Returns: + + """ + dfs = [] + datadict = self.get_parameter_data(*params, + start=start, + end=end) + for subdict in datadict.values(): + keys = list(subdict.keys()) + multiindex = pd.MultiIndex.from_arrays( + tuple(subdict[key].ravel() for key in keys[1:]), + names=keys[1:]) + df = pd.DataFrame(subdict[keys[0]].ravel(), index=multiindex, + columns=[keys[0]]) + dfs.append(df) + return dfs + def get_values(self, param_name: str) -> List[List[Any]]: """ Get the values (i.e. not NULLs) of the specified parameter From 0f75e4ddc79f892f1618bbfe28e6dc5714046599 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 20:21:42 +0100 Subject: [PATCH 417/719] Return dataframes in a dict too --- qcodes/dataset/data_set.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 072b7439e6a..ba75c5eac7d 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -861,15 +861,14 @@ def get_data_as_pandas_dataframe(self, List[pd.DataFrame]: """ Returns the values stored in the DataSet for the specified parameters - and their dependencies. If no paramerers are supplied the values will - be returned for all parameters that are not them self dependencies. + and their dependencies as a dict of Pandas DataFrames. Each element in + the dict is indexed by the names of the requested parameters. - The values are returned as a list of Pandas DataFrames. One for each - names of the parameters and its dependencies as keys and numpy arrays - of the data as values. If some of the parameters are stored as - arrays the remaining parameters are expanded to the same shape as these. - Apart from this expansion the data returned by this method - is the transpose of the date returned by `get_data`. + Each DataFrame contains a column for the data and is indexed by a + MultiIndex formed from all the setpoints of the parameter. + + If no parameters are supplied dataframes will be be returned for all + parameters that are not them self dependencies of other parameters. If provided, the start and end arguments select a range of results by result count (index). If the range is empty - that is, if the end is @@ -889,18 +888,18 @@ def get_data_as_pandas_dataframe(self, Returns: """ - dfs = [] + dfs = {} datadict = self.get_parameter_data(*params, start=start, end=end) - for subdict in datadict.values(): + for name, subdict in datadict.items(): keys = list(subdict.keys()) multiindex = pd.MultiIndex.from_arrays( tuple(subdict[key].ravel() for key in keys[1:]), names=keys[1:]) df = pd.DataFrame(subdict[keys[0]].ravel(), index=multiindex, columns=[keys[0]]) - dfs.append(df) + dfs[name] = df return dfs def get_values(self, param_name: str) -> List[List[Any]]: From 8994590bc73de504f3277db28a505f95a629702b Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 20:49:53 +0100 Subject: [PATCH 418/719] start testing dataframes --- qcodes/tests/dataset/helper_functions.py | 4 ++++ qcodes/tests/dataset/test_dataset_basic.py | 22 ++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index e74a4b84142..b1e6870c595 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -1,9 +1,12 @@ from typing import Sequence, Tuple, Dict import numpy as np +import pandas from numpy.testing import assert_array_equal + def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], + dataframe: Dict[str, pandas.DataFrame], parameter_names: Sequence[str], expected_names: Dict[str, Sequence[str]], expected_shapes: Dict[str, Sequence[Tuple[int, ...]]], @@ -13,6 +16,7 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], Args: data: The dict data to verify the shape and content of. + dataframe: The data represented as a dict of Pandas DataFrames. parameter_names: names of the parameters loaded as top level keys in the dict. expected_names: names of the parameters expected as keys in the second diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 58e49386ec1..bd65323edc6 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -1033,16 +1033,23 @@ def parameter_test_helper(ds, toplevel_names, end=None): data = ds.get_parameter_data(*toplevel_names, start=start, end=end) + dataframe = ds.get_data_as_pandas_dataframe(*toplevel_names, + start=start, + end=end) + all_data = ds.get_parameter_data(start=start, end=end) + all_dataframe = ds.get_data_as_pandas_dataframe(start=start, end=end) all_parameters = list(all_data.keys()) assert set(data.keys()).issubset(set(all_parameters)) + assert list(data.keys()) == list(dataframe.keys()) assert len(data.keys()) == len(toplevel_names) + assert len(dataframe.keys()) == len(toplevel_names) - verify_data_dict(data, toplevel_names, expected_names, expected_shapes, - expected_values) - verify_data_dict(all_data, toplevel_names, expected_names, expected_shapes, - expected_values) + verify_data_dict(data, dataframe, toplevel_names, expected_names, + expected_shapes, expected_values) + verify_data_dict(all_data, all_dataframe, toplevel_names, expected_names, + expected_shapes, expected_values) # Now lets remove a random element from the list # We do this one by one until there is only one element in the list @@ -1056,8 +1063,11 @@ def parameter_test_helper(ds, toplevel_names, subset_data = ds.get_parameter_data(*subset_names, start=start, end=end) - verify_data_dict(subset_data, subset_names, expected_names, - expected_shapes, expected_values) + subset_dataframe = ds.get_data_as_pandas_dataframe(*subset_names, + start=start, + end=end) + verify_data_dict(subset_data, subset_dataframe, subset_names, + expected_names, expected_shapes, expected_values) def limit_data_to_start_end(start, end, input_names, expected_names, From 5896b5e83b4946df74ac0a3772da5aef592ce463 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 20:50:41 +0100 Subject: [PATCH 419/719] handle the case where a dataframe is empty or the parameter has no values --- qcodes/dataset/data_set.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index ba75c5eac7d..6efe577febf 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -894,10 +894,16 @@ def get_data_as_pandas_dataframe(self, end=end) for name, subdict in datadict.items(): keys = list(subdict.keys()) - multiindex = pd.MultiIndex.from_arrays( - tuple(subdict[key].ravel() for key in keys[1:]), - names=keys[1:]) - df = pd.DataFrame(subdict[keys[0]].ravel(), index=multiindex, + if len(keys) == 0: + dfs[name] = {} + continue + if len(keys) == 1: + index = None + else: + index = pd.MultiIndex.from_arrays( + tuple(subdict[key].ravel() for key in keys[1:]), + names=keys[1:]) + df = pd.DataFrame(subdict[keys[0]].ravel(), index=index, columns=[keys[0]]) dfs[name] = df return dfs From fcbd23acdf55deb524a25150aff297bbf1ade7ad Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 20:53:47 +0100 Subject: [PATCH 420/719] return an empty dict --- qcodes/dataset/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 6efe577febf..806cff05ec1 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -895,7 +895,7 @@ def get_data_as_pandas_dataframe(self, for name, subdict in datadict.items(): keys = list(subdict.keys()) if len(keys) == 0: - dfs[name] = {} + dfs[name] = pd.DataFrame() continue if len(keys) == 1: index = None From df568a45fc627abdcdb30e56983f65e5f307feba Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 20:55:46 +0100 Subject: [PATCH 421/719] correct type --- qcodes/dataset/data_set.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 806cff05ec1..297cbc244be 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -858,7 +858,7 @@ def get_data_as_pandas_dataframe(self, _BaseParameter], start: Optional[int] = None, end: Optional[int] = None) -> \ - List[pd.DataFrame]: + Dict[str, pd.DataFrame]: """ Returns the values stored in the DataSet for the specified parameters and their dependencies as a dict of Pandas DataFrames. Each element in From 3e3a9e88091777af5d8af30db370b92bc671df76 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Sun, 16 Dec 2018 21:08:02 +0100 Subject: [PATCH 422/719] pass dataframe down one more level --- qcodes/tests/dataset/helper_functions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index b1e6870c595..5057ab078cc 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -29,15 +29,20 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], # check that all the expected parameters in the dict are # included in the list of parameters assert all(param in parameter_names for param in list(data.keys())) is True + assert all(param in parameter_names for + param in list(dataframe.keys())) is True for param in parameter_names: innerdata = data[param] + innerdataframe = dataframe[param] verify_data_dict_for_single_param(innerdata, + innerdataframe, expected_names[param], expected_shapes[param], expected_values[param]) def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], + dataframe: pandas.DataFrame, names: Sequence[str], shapes: Sequence[Tuple[int, ...]], values): From d4021963e75900afe2a0e319af5c74b9cf07dfd0 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 09:49:21 +0100 Subject: [PATCH 423/719] Enable assert introspection on helper module --- qcodes/tests/dataset/test_dataset_basic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index bd65323edc6..5199a78cece 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -29,7 +29,8 @@ # pylint: disable=unused-import from qcodes.tests.dataset.test_descriptions import some_paramspecs -from .helper_functions import verify_data_dict +pytest.register_assert_rewrite('qcodes.tests.dataset.helper_functions') +from qcodes.tests.dataset.helper_functions import verify_data_dict n_experiments = 0 From e35ba79ee8be8ffe85f5a7e33254f9a7b87f1a8f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 09:50:10 +0100 Subject: [PATCH 424/719] Start testing dataframes too --- qcodes/tests/dataset/helper_functions.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 5057ab078cc..8bc90d10a5d 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -47,7 +47,20 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], shapes: Sequence[Tuple[int, ...]], values): # check that there are no unexpected elements in the dict - assert all(param in names for param in list(datadict.keys())) is True + key_names = list(datadict.keys()) + assert set(key_names) == set(names) + # check that the dataframe has the same elements as index and columns + pandas_index_names = list(dataframe.index.names) + pandas_column_names = list(dataframe) + pandas_names = [] + for i in pandas_index_names: + if i is not None: + pandas_names.append(i) + for i in pandas_column_names: + if i is not None: + pandas_names.append(i) + assert set(pandas_names) == set(names) + for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape assert_array_equal(datadict[name], value) From 6128c1fd484b2ab4adea0405f258ea15aef5f16f Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 10:36:50 +0100 Subject: [PATCH 425/719] test content of dataframe --- qcodes/tests/dataset/helper_functions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 8bc90d10a5d..b90c4130cd5 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -1,4 +1,6 @@ from typing import Sequence, Tuple, Dict +from operator import mul +from functools import reduce import numpy as np import pandas @@ -61,6 +63,10 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], pandas_names.append(i) assert set(pandas_names) == set(names) + simpledf = dataframe.reset_index() + for name, shape, value in zip(names, shapes, values): assert datadict[name].shape == shape + assert len(simpledf[name]) == reduce(mul, shape) + assert_array_equal(dataframe.reset_index()[name].values, value.ravel()) assert_array_equal(datadict[name], value) From ada3b866c2eda8ea4b3c9e7f5e6f41920a71867c Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 11:29:40 +0100 Subject: [PATCH 426/719] Test multiindexes --- qcodes/tests/dataset/helper_functions.py | 38 +++++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index b90c4130cd5..08c4252d29e 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -14,18 +14,24 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], expected_shapes: Dict[str, Sequence[Tuple[int, ...]]], expected_values: Dict[str, Sequence[np.ndarray]]) -> None: """ - Simple helper function to verify a dict of data + Simple helper function to verify a dict of data. The expected names values + and shapes should be given as a dict with keys given by the dependent + parameters. Each value in the dicts should be the sequence of expected + names/shapes/values for that requested parameter and its dependencies. + The first element in the sequence must be the dependent parameter loaded. Args: data: The dict data to verify the shape and content of. dataframe: The data represented as a dict of Pandas DataFrames. - parameter_names: names of the parameters loaded as top level - keys in the dict. - expected_names: names of the parameters expected as keys in the second - level. - expected_shapes: expected shapes of the parameters loaded in the values - of the dict. - expected_values: expected content of the data arrays. + parameter_names: names of the parameters requested. These are expected + as top level keys in the dict. + expected_names: names of the parameters expected to be loaded for a + given parameter as a sequence indexed by the parameter. + expected_shapes: expected shapes of the parameters loaded. The shapes + should be stored as a tuple per parameter in a sequence containing + all the loaded parameters for a given requested parameter. + expected_values: expected content of the data arrays stored in a + sequence """ # check that all the expected parameters in the dict are @@ -63,6 +69,22 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], pandas_names.append(i) assert set(pandas_names) == set(names) + # lets check that the index is made up + # from all but the first column as expected + if len(values) > 1: + expected_index_values = values[1:] + index_values = dataframe.index.values + + nindexes = len(expected_index_values) + nrows = shapes[0] + + for row in range(len(nrows)): + row_index_values = index_values[row] + expected_values = \ + tuple(expected_index_values[indexnum].ravel()[row] + for indexnum in range(nindexes)) + assert row_index_values == expected_values + simpledf = dataframe.reset_index() for name, shape, value in zip(names, shapes, values): From d46e784a631051f1809ee1ffe6c35dbe6ae3f5a9 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 11:29:59 +0100 Subject: [PATCH 427/719] Make this test conform to the same layout as the rest --- qcodes/tests/dataset/test_dataset_basic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qcodes/tests/dataset/test_dataset_basic.py b/qcodes/tests/dataset/test_dataset_basic.py index 5199a78cece..924aaa387e4 100644 --- a/qcodes/tests/dataset/test_dataset_basic.py +++ b/qcodes/tests/dataset/test_dataset_basic.py @@ -783,13 +783,13 @@ def test_get_parameter_data(scalar_dataset, start, end): input_names = ['param_3'] expected_names = {} - expected_names['param_3'] = ['param_0', 'param_1', 'param_2', - 'param_3'] + expected_names['param_3'] = ['param_3', 'param_0', 'param_1', 'param_2'] expected_shapes = {} expected_shapes['param_3'] = [(10**3, )]*4 expected_values = {} - expected_values['param_3'] = [np.arange(10000*a, 10000*a+1000) - for a in range(4)] + expected_values['param_3'] = [np.arange(30000, 31000)] + \ + [np.arange(10000*a, 10000*a+1000) + for a in range(3)] start, end = limit_data_to_start_end(start, end, input_names, expected_names, expected_shapes, From 059e24daebac2777d10637070f23942818e6d8c5 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 12:41:14 +0100 Subject: [PATCH 428/719] Split pandas funcs out of test helper so that it can be used independently --- qcodes/tests/dataset/helper_functions.py | 33 +++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 08c4252d29e..25e58cbaeb1 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -1,5 +1,6 @@ from typing import Sequence, Tuple, Dict from operator import mul +from typing import Optional from functools import reduce import numpy as np @@ -8,13 +9,15 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], - dataframe: Dict[str, pandas.DataFrame], + dataframe: Optional[Dict[str, pandas.DataFrame]], parameter_names: Sequence[str], expected_names: Dict[str, Sequence[str]], expected_shapes: Dict[str, Sequence[Tuple[int, ...]]], expected_values: Dict[str, Sequence[np.ndarray]]) -> None: """ - Simple helper function to verify a dict of data. The expected names values + Simple helper function to verify a dict of data. It can also optionally + + The expected names values and shapes should be given as a dict with keys given by the dependent parameters. Each value in the dicts should be the sequence of expected names/shapes/values for that requested parameter and its dependencies. @@ -37,26 +40,40 @@ def verify_data_dict(data: Dict[str, Dict[str, np.ndarray]], # check that all the expected parameters in the dict are # included in the list of parameters assert all(param in parameter_names for param in list(data.keys())) is True - assert all(param in parameter_names for - param in list(dataframe.keys())) is True + if dataframe is not None: + assert all(param in parameter_names for + param in list(dataframe.keys())) is True for param in parameter_names: innerdata = data[param] - innerdataframe = dataframe[param] verify_data_dict_for_single_param(innerdata, - innerdataframe, expected_names[param], expected_shapes[param], expected_values[param]) + if dataframe is not None: + innerdataframe = dataframe[param] + verify_dataframe_for_single_param(innerdataframe, + expected_names[param], + expected_shapes[param], + expected_values[param]) def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], - dataframe: pandas.DataFrame, names: Sequence[str], shapes: Sequence[Tuple[int, ...]], values): # check that there are no unexpected elements in the dict key_names = list(datadict.keys()) assert set(key_names) == set(names) + + for name, shape, value in zip(names, shapes, values): + assert datadict[name].shape == shape + assert_array_equal(datadict[name], value) + + +def verify_dataframe_for_single_param(dataframe: pandas.DataFrame, + names: Sequence[str], + shapes: Sequence[Tuple[int, ...]], + values): # check that the dataframe has the same elements as index and columns pandas_index_names = list(dataframe.index.names) pandas_column_names = list(dataframe) @@ -88,7 +105,5 @@ def verify_data_dict_for_single_param(datadict: Dict[str, np.ndarray], simpledf = dataframe.reset_index() for name, shape, value in zip(names, shapes, values): - assert datadict[name].shape == shape assert len(simpledf[name]) == reduce(mul, shape) assert_array_equal(dataframe.reset_index()[name].values, value.ravel()) - assert_array_equal(datadict[name], value) From 135d7eadb2da4baa08a6dfdfb6d3764599d36404 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Mon, 17 Dec 2018 12:41:43 +0100 Subject: [PATCH 429/719] Adapt sqlite base tests to support new helpers --- qcodes/tests/dataset/test_sqlite_base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qcodes/tests/dataset/test_sqlite_base.py b/qcodes/tests/dataset/test_sqlite_base.py index 93ec6dc0d96..7b4b3489bfb 100644 --- a/qcodes/tests/dataset/test_sqlite_base.py +++ b/qcodes/tests/dataset/test_sqlite_base.py @@ -218,8 +218,8 @@ def test_get_parameter_data(scalar_dataset): expected_values = {} expected_values['param_3'] = [np.arange(10000*a, 10000*a+1000) for a in range(4)] - verify_data_dict(data, input_names, expected_names, expected_shapes, - expected_values) + verify_data_dict(data, None, input_names, expected_names, + expected_shapes, expected_values) def test_get_parameter_data_independent_parameters(standalone_parameters_dataset): @@ -249,7 +249,7 @@ def test_get_parameter_data_independent_parameters(standalone_parameters_dataset expected_values['param_3'] = [np.arange(30000, 30000 + 1000), np.arange(0, 1000)] - verify_data_dict(data, expected_toplevel_params, expected_names, + verify_data_dict(data, None, expected_toplevel_params, expected_names, expected_shapes, expected_values) From a1bdb5c5a030ded1bfe64b35b34a7ab8a7250228 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 18 Dec 2018 12:43:46 +0100 Subject: [PATCH 430/719] Don't return multiindexes for 1d index data --- qcodes/dataset/data_set.py | 2 ++ qcodes/tests/dataset/helper_functions.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 297cbc244be..28d7d2d495e 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -899,6 +899,8 @@ def get_data_as_pandas_dataframe(self, continue if len(keys) == 1: index = None + elif len(keys) == 2: + index = pd.Index(subdict[keys[1]].ravel(), name=keys[1]) else: index = pd.MultiIndex.from_arrays( tuple(subdict[key].ravel() for key in keys[1:]), diff --git a/qcodes/tests/dataset/helper_functions.py b/qcodes/tests/dataset/helper_functions.py index 25e58cbaeb1..8238c7910ed 100644 --- a/qcodes/tests/dataset/helper_functions.py +++ b/qcodes/tests/dataset/helper_functions.py @@ -97,6 +97,12 @@ def verify_dataframe_for_single_param(dataframe: pandas.DataFrame, for row in range(len(nrows)): row_index_values = index_values[row] + # one dimensional arrays will have single values for there indexed + # not tuples as they don't use multiindex. Put these in tuples + # for easy comparison + if not isinstance(dataframe.index, pandas.MultiIndex): + row_index_values = (row_index_values,) + expected_values = \ tuple(expected_index_values[indexnum].ravel()[row] for indexnum in range(nindexes)) From fd435adc298bbc30a486dbadd8108292907ac26e Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 13:39:05 +0100 Subject: [PATCH 431/719] Add DataSet to public api --- docs/api/public.rst | 2 ++ docs/conf.py | 1 + qcodes/dataset/data_set.py | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/api/public.rst b/docs/api/public.rst index 302e6ae104e..9a8bff909dd 100644 --- a/docs/api/public.rst +++ b/docs/api/public.rst @@ -95,7 +95,9 @@ DataSet qcodes.dataset.database.initialise_database qcodes.dataset.database.initialise_or_create_database_at + qcodes.dataset.data_set.DataSet qcodes.dataset.data_set.load_by_id + qcodes.dataset.data_set.load_by_guid qcodes.dataset.plotting.plot_by_id diff --git a/docs/conf.py b/docs/conf.py index 7a320545dff..048556b47fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -358,6 +358,7 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { + 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None), 'matplotlib': ('https://matplotlib.org/', None), 'python': ('https://docs.python.org/3.6', None), 'numpy': ('https://docs.scipy.org/doc/numpy', None), diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index 28d7d2d495e..b361bba2fd1 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -873,7 +873,7 @@ def get_data_as_pandas_dataframe(self, If provided, the start and end arguments select a range of results by result count (index). If the range is empty - that is, if the end is less than or equal to the start, or if start is after the current end - of the DataSet – then a list of empty arrays is returned. + of the DataSet – then a dict of empty dataframes is returned. Args: *params: string parameter names, QCoDeS Parameter objects, and From da0eb57d982b817c2b714b77ce6f4e2eef6bb608 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 15:18:52 +0100 Subject: [PATCH 432/719] Improve docstring --- qcodes/dataset/data_set.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/qcodes/dataset/data_set.py b/qcodes/dataset/data_set.py index b361bba2fd1..696f8df7029 100644 --- a/qcodes/dataset/data_set.py +++ b/qcodes/dataset/data_set.py @@ -861,19 +861,23 @@ def get_data_as_pandas_dataframe(self, Dict[str, pd.DataFrame]: """ Returns the values stored in the DataSet for the specified parameters - and their dependencies as a dict of Pandas DataFrames. Each element in - the dict is indexed by the names of the requested parameters. + and their dependencies as a dict of :py:class:`pandas.DataFrame`\s + Each element in the dict is indexed by the names of the requested + parameters. Each DataFrame contains a column for the data and is indexed by a - MultiIndex formed from all the setpoints of the parameter. + :py:class:`pandas.MultiIndex` formed from all the setpoints + of the parameter. - If no parameters are supplied dataframes will be be returned for all - parameters that are not them self dependencies of other parameters. + If no parameters are supplied data will be be + returned for all parameters in the dataset that are not them self + dependencies of other parameters. If provided, the start and end arguments select a range of results by result count (index). If the range is empty - that is, if the end is less than or equal to the start, or if start is after the current end - of the DataSet – then a dict of empty dataframes is returned. + of the DataSet – then a dict of empty :py:class:`pandas.DataFrame`\s is + returned. Args: *params: string parameter names, QCoDeS Parameter objects, and @@ -886,7 +890,10 @@ def get_data_as_pandas_dataframe(self, None Returns: - + Dictionary from requested parameter names to + :py:class:`pandas.DataFrame`\s with the requested parameter as + a column and a indexed by a :py:class:`pandas.MultiIndex` formed + by the dependencies. """ dfs = {} datadict = self.get_parameter_data(*params, From cd354fee5ca616d84d23d55fd5bcbd19c8a0c5a1 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 15:52:58 +0100 Subject: [PATCH 433/719] Fix ambiguous type --- qcodes/data/format.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qcodes/data/format.py b/qcodes/data/format.py index 0f8f012e5b4..03e6ab21b7b 100644 --- a/qcodes/data/format.py +++ b/qcodes/data/format.py @@ -2,6 +2,11 @@ from traceback import format_exc from operator import attrgetter import logging +from typing import TYPE_CHECKING, Set + +if TYPE_CHECKING: + from .data_set import DataSet + log = logging.getLogger(__name__) @@ -69,7 +74,7 @@ def write(self, data_set, io_manager, location, write_metadata=True, """ raise NotImplementedError - def read(self, data_set): + def read(self, data_set: 'DataSet') -> None: """ Read the entire ``DataSet``. @@ -80,7 +85,7 @@ def read(self, data_set): initialization functionality defined here. Args: - data_set (DataSet): the data to read into. Should already have + data_set: the data to read into. Should already have attributes ``io`` (an io manager), ``location`` (string), and ``arrays`` (dict of ``{array_id: array}``, can be empty or can already have some or all of the arrays present, they @@ -100,7 +105,7 @@ def read(self, data_set): self.read_metadata(data_set) - ids_read = set() + ids_read: Set[str] = set() for fn in data_files: with io_manager.open(fn, 'r') as f: try: From 3949a8d7b5c3c3c41c30b2dce8871df8453d81e7 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 16:13:00 +0100 Subject: [PATCH 434/719] remove all non explicit refs to dataset --- qcodes/data/format.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/qcodes/data/format.py b/qcodes/data/format.py index 03e6ab21b7b..43f3b458735 100644 --- a/qcodes/data/format.py +++ b/qcodes/data/format.py @@ -53,7 +53,7 @@ class Formatter: """ ArrayGroup = namedtuple('ArrayGroup', 'shape set_arrays data name') - def write(self, data_set, io_manager, location, write_metadata=True, + def write(self, data_set: DataSet, io_manager, location, write_metadata=True, force_write=False, only_complete=True): """ Write the DataSet to storage. @@ -64,7 +64,7 @@ def write(self, data_set, io_manager, location, write_metadata=True, and when to just append or otherwise update the file(s). Args: - data_set (DataSet): the data we are writing. + data_set: the data we are writing. io_manager (io_manager): base physical location to write to. location (str): the file location within the io_manager. write_metadata (bool): if True, then the metadata is written to disk @@ -114,14 +114,15 @@ def read(self, data_set: 'DataSet') -> None: log.warning('error reading file ' + fn) log.warning(format_exc()) - def write_metadata(self, data_set, io_manager, location, read_first=True): + def write_metadata(self, data_set: 'DataSet', + io_manager, location, read_first=True): """ Write the metadata for this DataSet to storage. Subclasses must override this method. Args: - data_set (DataSet): the data we are writing. + data_set: the data we are writing. io_manager (io_manager): base physical location to write to. location (str): the file location within the io_manager. read_first (bool, optional): whether to first look for previously @@ -130,18 +131,18 @@ def write_metadata(self, data_set, io_manager, location, read_first=True): """ raise NotImplementedError - def read_metadata(self, data_set): + def read_metadata(self, data_set: 'DataSet'): """ Read the metadata from this DataSet from storage. Subclasses must override this method. Args: - data_set (DataSet): the data to read metadata into + data_set: the data to read metadata into """ raise NotImplementedError - def read_one_file(self, data_set, f, ids_read): + def read_one_file(self, data_set: 'DataSet', f, ids_read): """ Read data from a single file into a ``DataSet``. @@ -150,7 +151,7 @@ def read_one_file(self, data_set, f, ids_read): time, or ``read`` which finds matching files on its own. Args: - data_set (DataSet): the data we are reading into. + data_set: the data we are reading into. f (file-like): a file-like object to read from, as provided by ``io_manager.open``. From 47a14075f486d17052f734a34f8c7b9e5b4f6175 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 16:17:00 +0100 Subject: [PATCH 435/719] This needs to be a forward ref --- qcodes/data/format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/data/format.py b/qcodes/data/format.py index 43f3b458735..79ac290cd30 100644 --- a/qcodes/data/format.py +++ b/qcodes/data/format.py @@ -53,7 +53,7 @@ class Formatter: """ ArrayGroup = namedtuple('ArrayGroup', 'shape set_arrays data name') - def write(self, data_set: DataSet, io_manager, location, write_metadata=True, + def write(self, data_set: 'DataSet', io_manager, location, write_metadata=True, force_write=False, only_complete=True): """ Write the DataSet to storage. From 2d259dcfe93756377281937db03ed9afc89cdb21 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Fri, 21 Dec 2018 16:35:35 +0100 Subject: [PATCH 436/719] Same for the gnuplot formatter --- qcodes/data/gnuplot_format.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/qcodes/data/gnuplot_format.py b/qcodes/data/gnuplot_format.py index 82512a8f3d1..4e0cd9c9b37 100644 --- a/qcodes/data/gnuplot_format.py +++ b/qcodes/data/gnuplot_format.py @@ -7,6 +7,10 @@ from qcodes.utils.helpers import deep_update, NumpyJSONEncoder from .data_array import DataArray from .format import Formatter +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .data_set import DataSet log = logging.getLogger(__name__) @@ -243,15 +247,16 @@ def _get_labels(self, labelstr): parts = re.split('"\\s+"', labelstr[1:-1]) return [l.replace('\\"', '"').replace('\\\\', '\\') for l in parts] - def write(self, data_set, io_manager, location, force_write=False, - write_metadata=True, only_complete=True, filename=None): + def write(self, data_set: 'DataSet', io_manager, location, + force_write=False, write_metadata=True, only_complete=True, + filename=None): """ Write updates in this DataSet to storage. Will choose append if possible, overwrite if not. Args: - data_set (DataSet): the data we're storing + data_set: the data we're storing io_manager (io_manager): the base location to write to location (str): the file location within io_manager only_complete (bool): passed to match_save_range, answers the @@ -336,12 +341,13 @@ def write(self, data_set, io_manager, location, force_write=False, self.write_metadata( data_set, io_manager=io_manager, location=location) - def write_metadata(self, data_set, io_manager, location, read_first=True): + def write_metadata(self, data_set: 'DataSet', io_manager, location, + read_first=True): """ Write all metadata in this DataSet to storage. Args: - data_set (DataSet): the data we're storing + data_set: the data we're storing io_manager (io_manager): the base location to write to From e551376c815a7c1dc592f78e3d6c87f1b3deb7a7 Mon Sep 17 00:00:00 2001 From: nyxus Date: Fri, 21 Dec 2018 16:47:11 +0100 Subject: [PATCH 437/719] RTO1000 driver: Added is_triggered, is_running and is acquiring functions, trigger value_mapping to validator, Fixed typos; Added measurement to the RTO1000 example program --- ...Schwarz RTO 1000 series Oscilloscope.ipynb | 1296 ++++------------- .../rohde_schwarz/RTO1000.py | 26 +- 2 files changed, 339 insertions(+), 983 deletions(-) diff --git a/docs/examples/driver_examples/Qcodes example with Rohde Schwarz RTO 1000 series Oscilloscope.ipynb b/docs/examples/driver_examples/Qcodes example with Rohde Schwarz RTO 1000 series Oscilloscope.ipynb index 3837ada70e7..6b900285068 100644 --- a/docs/examples/driver_examples/Qcodes example with Rohde Schwarz RTO 1000 series Oscilloscope.ipynb +++ b/docs/examples/driver_examples/Qcodes example with Rohde Schwarz RTO 1000 series Oscilloscope.ipynb @@ -10,7 +10,12 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:00.839361Z", + "start_time": "2018-12-21T15:20:59.084361Z" + } + }, "outputs": [], "source": [ "%matplotlib notebook\n", @@ -23,24 +28,36 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:00.909861Z", + "start_time": "2018-12-21T15:21:00.841361Z" + } + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connected to: Rohde&Schwarz RTO (serial:1316.1000k44/400363, firmware:3.70.1.0) in 0.23s\n" + "Connected to: Rohde&Schwarz RTO (serial:1316.1000k24/400376, firmware:3.70.1.0) in 0.06s\n" ] } ], "source": [ - "rto = RTO1000('rto', 'TCPIP0::172.20.3.86::inst0::INSTR')" + "# Select your scope based on its ip address\n", + "# rto = RTO1000('rto', 'TCPIP0::172.20.3.86::inst0::INSTR')\n", + "rto = RTO1000('rto', 'TCPIP0::192.168.0.3::inst0::INSTR', model='RTO1024')" ] }, { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:00.913861Z", + "start_time": "2018-12-21T15:21:00.910861Z" + } + }, "outputs": [], "source": [ "# Before we do anything, let's make sure that the instrument is in a clean state\n", @@ -53,7 +70,12 @@ { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:00.949361Z", + "start_time": "2018-12-21T15:21:00.945861Z" + } + }, "outputs": [], "source": [ "# The display should be set to 'remote' for better performance regarding data acquisition\n", @@ -65,102 +87,14 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "rto:\n", - "\tparameter value\n", - "--------------------------------------------------------------------------------\n", - "IDN :\t{'firmware': '3.70.1.0', 'serial': '1316.1000k44/...\n", - "acquisition_sample_rate :\t1e+10 (Sa/s)\n", - "completed_acquisitions :\t270421 \n", - "dataformat :\tASC,0 \n", - "display :\tview \n", - "high_definition_bandwidth :\t1e+06 (Hz)\n", - "high_definition_state :\tOFF \n", - "num_acquisitions :\t1 \n", - "run_mode :\tRUN CONT \n", - "sampling_rate :\t10000000000 (Sa/s)\n", - "timebase_position :\t0 (s)\n", - "timebase_range :\t1e-07 (s)\n", - "timebase_scale :\t1e-08 (s/div)\n", - "timeout :\t5 (s)\n", - "trigger_display :\tOFF \n", - "trigger_edge_slope :\tPOS \n", - "trigger_level :\t0 \n", - "trigger_source :\tCH1 \n", - "trigger_type :\tEDGE \n", - "rto_channel3:\n", - "\tparameter value\n", - "--------------------------------------------------------------------------------\n", - "arithmetics :\tOFF \n", - "bandwidth :\tFULL \n", - "coupling :\tDCL \n", - "ground :\t0 \n", - "impedance :\t50 (Ohm)\n", - "invert :\t0 \n", - "offset :\t0 (V)\n", - "overload :\t0 \n", - "position :\t0 (div)\n", - "range :\t0.5 (V)\n", - "scale :\t0.05 (V/div)\n", - "state :\t0 \n", - "trace :\tNot available (V)\n", - "rto_channel4:\n", - "\tparameter value\n", - "--------------------------------------------------------------------------------\n", - "arithmetics :\tOFF \n", - "bandwidth :\tFULL \n", - "coupling :\tDCL \n", - "ground :\t0 \n", - "impedance :\t50 (Ohm)\n", - "invert :\t0 \n", - "offset :\t0 (V)\n", - "overload :\t0 \n", - "position :\t0 (div)\n", - "range :\t0.5 (V)\n", - "scale :\t0.05 (V/div)\n", - "state :\t0 \n", - "trace :\tNot available (V)\n", - "rto_channel2:\n", - "\tparameter value\n", - "--------------------------------------------------------------------------------\n", - "arithmetics :\tOFF \n", - "bandwidth :\tFULL \n", - "coupling :\tDCL \n", - "ground :\t0 \n", - "impedance :\t50 (Ohm)\n", - "invert :\t0 \n", - "offset :\t0 (V)\n", - "overload :\t0 \n", - "position :\t0 (div)\n", - "range :\t0.5 (V)\n", - "scale :\t0.05 (V/div)\n", - "state :\t0 \n", - "trace :\tNot available (V)\n", - "rto_channel1:\n", - "\tparameter value\n", - "--------------------------------------------------------------------------------\n", - "arithmetics :\tOFF \n", - "bandwidth :\tFULL \n", - "coupling :\tDCL \n", - "ground :\t0 \n", - "impedance :\t50 (Ohm)\n", - "invert :\t0 \n", - "offset :\t0 (V)\n", - "overload :\t0 \n", - "position :\t0 (div)\n", - "range :\t0.5 (V)\n", - "scale :\t0.05 (V/div)\n", - "state :\t1 \n", - "trace :\tNot available (V)\n" - ] + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T11:03:26.701022Z", + "start_time": "2018-12-21T11:00:30.886366Z" } - ], + }, + "outputs": [], "source": [ "# To get an overview of all instrument settings, print_readable_sanpshot is great\n", "rto.print_readable_snapshot(update=True)" @@ -187,8 +121,13 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:07.927861Z", + "start_time": "2018-12-21T15:21:07.923861Z" + } + }, "outputs": [], "source": [ "rto.ch1.coupling('DC') # 'DC' means DC 50 Ohm, 'DCLimit' means DC 1 MOhm, 'AC' means AC 1 MOhm.\n", @@ -206,8 +145,13 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:08.990361Z", + "start_time": "2018-12-21T15:21:08.979861Z" + } + }, "outputs": [], "source": [ "rto.trigger_source('CH1')\n", @@ -227,8 +171,13 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:10.215361Z", + "start_time": "2018-12-21T15:21:10.211861Z" + } + }, "outputs": [], "source": [ "rto.run_cont() # run continuously" @@ -245,9 +194,12 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:11.334861Z", + "start_time": "2018-12-21T15:21:11.331361Z" + } }, "outputs": [], "source": [ @@ -266,8 +218,13 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:14.559361Z", + "start_time": "2018-12-21T15:21:14.555861Z" + } + }, "outputs": [], "source": [ "# This is EXACTLY matching the waveform...\n", @@ -277,9 +234,12 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:16.710361Z", + "start_time": "2018-12-21T15:21:16.707361Z" + } }, "outputs": [], "source": [ @@ -303,8 +263,13 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, + "execution_count": 11, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:18.917361Z", + "start_time": "2018-12-21T15:21:18.906361Z" + } + }, "outputs": [], "source": [ "# Let's do 1000 averages of our sine wave\n", @@ -316,9 +281,12 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:21.334361Z", + "start_time": "2018-12-21T15:21:21.330361Z" + } }, "outputs": [], "source": [ @@ -337,9 +305,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:24.054861Z", + "start_time": "2018-12-21T15:21:24.050861Z" + } }, "outputs": [], "source": [ @@ -351,8 +322,13 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, + "execution_count": 14, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:26.051361Z", + "start_time": "2018-12-21T15:21:26.048361Z" + } + }, "outputs": [], "source": [ "##########################\n", @@ -367,8 +343,13 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, + "execution_count": 15, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:27.625861Z", + "start_time": "2018-12-21T15:21:27.490361Z" + } + }, "outputs": [], "source": [ "# Next, the trace must be prepared. This ensures that all settings are correct\n", @@ -377,18 +358,23 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, + "execution_count": 16, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:29.821861Z", + "start_time": "2018-12-21T15:21:28.528861Z" + } + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DataSet:\n", - " location = 'data/2017-12-14/#007_{name}_10-09-48'\n", + " location = 'data/2018-12-21/#003_{name}_16-21-28'\n", " | | | \n", " Measured | trace | trace | (100000,)\n", - "acquired at 2017-12-14 10:09:49\n" + "acquired at 2018-12-21 16:21:29\n" ] }, { @@ -473,7 +459,7 @@ " };\n", "\n", " this.imageObj.onunload = function() {\n", - " this.ws.close();\n", + " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", @@ -948,9 +934,9 @@ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", " this.message.textContent = tooltip;\n", "};\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", "\n", - "mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", "\n", "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", " // Create a \"websocket\"-like object which calls the given IPython comm\n", @@ -968,7 +954,7 @@ " // Register the callback with on_msg.\n", " comm.on_msg(function(msg) {\n", " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overriden (by mpl) onmessage function.\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", " ws.onmessage(msg['content']['data'])\n", " });\n", " return ws;\n", @@ -1120,9 +1106,12 @@ " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", @@ -1171,7 +1160,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -1189,18 +1178,23 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, + "execution_count": 17, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:21:39.668861Z", + "start_time": "2018-12-21T15:21:38.208861Z" + } + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DataSet:\n", - " location = 'data/2017-12-14/#008_{name}_10-09-51'\n", + " location = 'data/2018-12-21/#004_{name}_16-21-38'\n", " | | | \n", " Measured | trace | trace | (100000,)\n", - "acquired at 2017-12-14 10:09:52\n" + "acquired at 2018-12-21 16:21:39\n" ] }, { @@ -1285,7 +1279,7 @@ " };\n", "\n", " this.imageObj.onunload = function() {\n", - " this.ws.close();\n", + " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", @@ -1760,9 +1754,9 @@ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", " this.message.textContent = tooltip;\n", "};\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", "\n", - "mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", "\n", "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", " // Create a \"websocket\"-like object which calls the given IPython comm\n", @@ -1780,7 +1774,7 @@ " // Register the callback with on_msg.\n", " comm.on_msg(function(msg) {\n", " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overriden (by mpl) onmessage function.\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", " ws.onmessage(msg['content']['data'])\n", " });\n", " return ws;\n", @@ -1932,9 +1926,12 @@ " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", @@ -1983,7 +1980,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2015,9 +2012,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 18, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:52.234861Z", + "start_time": "2018-12-21T15:21:52.231361Z" + } }, "outputs": [], "source": [ @@ -2027,9 +2027,12 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 19, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:55.264861Z", + "start_time": "2018-12-21T15:21:55.126861Z" + } }, "outputs": [], "source": [ @@ -2038,9 +2041,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 20, "metadata": { - "collapsed": true + "ExecuteTime": { + "end_time": "2018-12-21T15:21:56.419361Z", + "start_time": "2018-12-21T15:21:56.414861Z" + } }, "outputs": [], "source": [ @@ -2051,18 +2057,24 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, + "execution_count": 21, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:22:07.554861Z", + "start_time": "2018-12-21T15:21:57.837861Z" + }, + "scrolled": true + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DataSet:\n", - " location = 'data/2017-12-14/#011_{name}_10-43-29'\n", + " location = 'data/2018-12-21/#005_{name}_16-21-58'\n", " | | | \n", " Measured | trace | trace | (1000000,)\n", - "acquired at 2017-12-14 10:43:50\n" + "acquired at 2018-12-21 16:22:07\n" ] }, { @@ -2147,7 +2159,7 @@ " };\n", "\n", " this.imageObj.onunload = function() {\n", - " this.ws.close();\n", + " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", @@ -2622,9 +2634,9 @@ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", " this.message.textContent = tooltip;\n", "};\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", "\n", - "mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", "\n", "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", " // Create a \"websocket\"-like object which calls the given IPython comm\n", @@ -2642,7 +2654,7 @@ " // Register the callback with on_msg.\n", " comm.on_msg(function(msg) {\n", " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overriden (by mpl) onmessage function.\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", " ws.onmessage(msg['content']['data'])\n", " });\n", " return ws;\n", @@ -2794,9 +2806,12 @@ " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", @@ -2845,7 +2860,7 @@ { "data": { "text/html": [ - "" + "
" ], "text/plain": [ "" @@ -2862,828 +2877,142 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:22:49.949861Z", + "start_time": "2018-12-21T15:22:07.556861Z" + } + }, + "outputs": [], + "source": [ + "# We can see the averaging effect by increasing the number of averages\n", + "\n", + "rto.num_acquisitions(500)\n", + "rto.ch1.arithmetics('AVERAGE') # other options: 'ENVELOPE' and 'OFF'\n", + "rto.run_single() # and perform a single run. NOTE: YOU MUST CALL THIS AS THE LAST THING BEFORE GETTING THE TRACE!!!\n", + "data_avgd = qc.Measure(rto.ch1.trace).run()\n", + "plot = qc.MatPlot(data_avgd.arrays['trace'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T13:17:01.236984Z", + "start_time": "2018-12-21T13:17:01.233484Z" + }, + "collapsed": true + }, + "source": [ + "# Measurements\n", + "Start 1 of the 8 mesurements" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:23:06.811361Z", + "start_time": "2018-12-21T15:23:06.804861Z" + } + }, + "outputs": [], + "source": [ + "import time\n", + "\n", + "def do_measurement(rto, nr_measurements, nr_samples):\n", + " \"\"\"\n", + " Will clean prevous measurement en start a new one\n", + " Args:\n", + " rto: scope driver object\n", + " nr_measurements: number of used/enabled measurements (up to 8)\n", + " nr_samples: minimal number of samples before the measurement will stop\n", + " \"\"\"\n", + " # Clear the prevous mesurement\n", + " for meas_ch in range(1, nr_measurements + 1):\n", + " rto.submodules['meas{}'.format(meas_ch)].clear()\n", + " rto.opc()\n", + " rto.run_continues()\n", + " \n", + " # Check if measurement is running\n", + " if(rto.is_acquiring() == False):\n", + " raise RuntimeError('Cannot start measuremet; scope is not trigged')\n", + " \n", + " # Wait for the scope to be ready\n", + " while rto.submodules['meas{}'.format(nr_measurements)].event_count() < 10:\n", + " time.sleep(0.1)\n", + " rto.opc() \n", + "\n", + " ## Actual measurement \n", + " for meas_ch in range(1, nr_measurements + 1):\n", + " rto.submodules['meas{}'.format(meas_ch)].clear()\n", + " while rto.submodules['meas{}'.format(nr_measurements)].event_count() < nr_samples:\n", + " time.sleep(0.1)\n", + " rto.stop_opc()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:25:39.973861Z", + "start_time": "2018-12-21T15:25:39.884861Z" + } + }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "DataSet:\n", - " location = 'data/2017-12-14/#012_{name}_10-45-40'\n", - " | | | \n", - " Measured | trace | trace | (1000000,)\n", - "acquired at 2017-12-14 10:46:46\n" + "Wait for results\n", + "Ch: 1; frequency: 100kHz\n" ] - }, + } + ], + "source": [ + "rto.timebase_range(1.5 * (1/100e3)) # Need a bit more than 1 period \n", + "rto.ch1.range(0.11) # Need a bit more the 100mV\n", + "\n", + "# Configure measurement 1 to determine frequency \n", + "rto.meas1.enable(\"ON\")\n", + "rto.meas1.source(\"C1W1\") # See rto.meas1.sources for more options\n", + "rto.meas1.category(\"AMPTime\") # See rto.meas1.categories for more options\n", + "rto.meas1.main(\"FREQuency\") # See rto.meas1.meas_type for more options\n", + "rto.meas1.clear()\n", + "rto.meas1.statistics_enable(\"ON\")\n", + "rto.run_continues()\n", + "\n", + "#start measurement\n", + "print(\"Wait for results\")\n", + "do_measurement(rto, 1, 500)\n", + "actualFq = rto.meas1.result_avg() * 1e-3\n", + "print(f\"Ch: 1; frequency: {actualFq:.0f}kHz\")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "ExecuteTime": { + "end_time": "2018-12-21T15:25:06.628361Z", + "start_time": "2018-12-21T15:25:06.624361Z" + } + }, + "outputs": [ { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " this.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "([], [None])" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot_by_id(runid)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case we are not measuring any signal so as expected we see noise" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Averaging" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The driver supports averaging over multiple traces simply by setting the number of averages" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "sh.avg(10)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 742\n" - ] - } - ], - "source": [ - "meas = Measurement()\n", - "meas.register_parameter(sh.trace)\n", - "\n", - "with meas.run() as datasaver:\n", - " datasaver.add_result((sh.trace, sh.trace(),))\n", - " runid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "([], [None])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plot_by_id(runid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case we are not measuring any signal so as expected we see noise" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Averaging" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The driver supports averaging over multiple traces simply by setting the number of averages" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "sh.avg(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 358\n" + ] + } + ], + "source": [ + "meas = Measurement()\n", + "meas.register_parameter(sh.trace)\n", + "\n", + "with meas.run() as datasaver:\n", + " datasaver.add_result((sh.trace, sh.trace(),))\n", + " runid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ax, abax = plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 72\n" - ] - } - ], - "source": [ - "# Looking at the above picture, we may decide to sample more finely in the central\n", - "# region\n", - "\n", - "with meas.run() as datasaver:\n", - "\n", - " v1points = np.concatenate((np.linspace(-1, -0.5, 5),\n", - " np.linspace(-0.51, 0.5, 200),\n", - " np.linspace(0.51, 1, 5)))\n", - " v2points = np.concatenate((np.linspace(-1, -0.25, 5),\n", - " np.linspace(-0.26, 0.5, 200),\n", - " np.linspace(0.51, 1, 5)))\n", - " \n", - " for v1 in v1points:\n", - " for v2 in v2points:\n", - " dac.ch1(v1)\n", - " dac.ch2(v2)\n", - " val = dmm.v1.get()\n", - " datasaver.add_result((dac.ch1, v1),\n", - " (dac.ch2, v2),\n", - " (dmm.v1, val))\n", - "\n", - " dataid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ax, cbax = plot_by_id(dataid)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## Random sampling " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We may also chose to sample completly randomly across the phase space" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "gauss = gauss_model(0.1, 0.2, 0.25)\n", - "next(gauss)\n", - "\n", - "def measure_gauss(x, y):\n", - " val = gauss.send((x, y))\n", - " next(gauss)\n", - " return val\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 74\n" - ] - } - ], - "source": [ - "v1_points = np.linspace(-1, 1, 250)\n", - "v2_points = np.linspace(1, -1, 250)\n", - "\n", - "threshold = 0.25\n", - "\n", - "npoints = 5000\n", - "\n", - "with meas.run() as datasaver:\n", - " for i in range(npoints):\n", - " x = 2*(np.random.rand()-.5)\n", - " y = 2*(np.random.rand()-.5)\n", - " z = measure_gauss(x,y)\n", - " datasaver.add_result((dac.ch1, x),\n", - " (dac.ch2, y),\n", - " (dmm.v1, z))\n", - "dataid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ax, cbax = plot_by_id(run_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## Subscriptions\n", - "\n", - "The Measurement object can also handle subscriptions to the dataset. Subscriptions are really, under the hood, triggers in the underlying SQLite database. Therefore, the subscribers are only called when data is written to the database (which happens every `write_period`).\n", - "\n", - "When making a subscription, two things must be supplied, a function and a mutable state object. The function **MUST** have a call signature of `f(result_list, length, state, **kwargs)`, where result_list is a list of tuples of parameter values inserted in the dataset, length is an integer (the step number of the run), and state is the mutable state object. The function does not need to actually use these arguments, but the call signature must match this.\n", - "\n", - "We show two examples of subscribtions here." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Subscription example 1: simple printing" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 76\n", - "Added points to measurement, step 0.\n", - "Added points to measurement, step 1.\n", - "The run now holds 1 rows\n", - "Added points to measurement, step 2.\n", - "Added points to measurement, step 3.\n", - "Added points to measurement, step 4.\n", - "The run now holds 6 rows\n", - "Added points to measurement, step 5.\n", - "Added points to measurement, step 6.\n", - "Added points to measurement, step 7.\n", - "The run now holds 9 rows\n", - "Added points to measurement, step 8.\n", - "Added points to measurement, step 9.\n", - "The run now holds 10 rows\n", - "The run now holds 10 rows\n", - "The run now holds 10 rows\n" - ] - } - ], - "source": [ - "\n", - "\n", - "def print_which_step(results_list, length, state):\n", - " \"\"\"\n", - " This subscriber does not use results_list nor state; it simply\n", - " prints how many results we have added to the database\n", - " \"\"\"\n", - " print(f'The run now holds {length} rows')\n", - " \n", - " \n", - "meas = Measurement()\n", - "meas.register_parameter(dac.ch1)\n", - "meas.register_parameter(dmm.v1, setpoints=(dac.ch1,))\n", - "\n", - "meas.write_period = 1 # We write to the database every 1 second\n", - "\n", - "meas.add_subscriber(print_which_step, state=[])\n", - "\n", - "with meas.run() as datasaver:\n", - " for n in range(10):\n", - " datasaver.add_result((dac.ch1, n), (dmm.v1, n**2))\n", - " print(f'Added points to measurement, step {n}.')\n", - " sleep(0.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Subscription example 2: using the state\n", - "\n", - "We add two subscribers now." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 77\n", - "Added points to measurement, step 0.\n", - "First parameter value list: []\n", - "Added points to measurement, step 1.\n", - "First parameter value list: []\n", - "The run now holds 2 rows\n", - "Added points to measurement, step 2.\n", - "First parameter value list: [0, 1, 2]\n", - "Added points to measurement, step 3.\n", - "First parameter value list: [0, 1, 2]\n", - "Added points to measurement, step 4.\n", - "First parameter value list: [0, 1, 2]\n", - "The run now holds 5 rows\n", - "Added points to measurement, step 5.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5]\n", - "Added points to measurement, step 6.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5]\n", - "Added points to measurement, step 7.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5]\n", - "The run now holds 7 rows\n", - "Added points to measurement, step 8.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7, 8]\n", - "Added points to measurement, step 9.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7, 8]\n", - "The run now holds 10 rows\n", - "The run now holds 10 rows\n", - "The run now holds 10 rows\n" - ] - } - ], - "source": [ - "\n", - "\n", - "def get_list_of_first_param(results_list, lenght, state):\n", - " \"\"\"\n", - " Modify the state (a list) to hold all the values for\n", - " the first parameter\n", - " \"\"\"\n", - " param_vals = [parvals[0] for parvals in results_list]\n", - " state += param_vals\n", - " \n", - "meas = Measurement()\n", - "meas.register_parameter(dac.ch1)\n", - "meas.register_parameter(dmm.v1, setpoints=(dac.ch1,))\n", - "\n", - "meas.write_period = 1 # We write to the database every 1 second\n", - "\n", - "first_param_list = []\n", - "\n", - "meas.add_subscriber(print_which_step, state=[])\n", - "meas.add_subscriber(get_list_of_first_param, state=first_param_list)\n", - "\n", - "with meas.run() as datasaver:\n", - " for n in range(10):\n", - " datasaver.add_result((dac.ch1, n), (dmm.v1, n**2))\n", - " print(f'Added points to measurement, step {n}.')\n", - " print(f'First parameter value list: {first_param_list}')\n", - " sleep(0.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## QCoDeS Array and MultiParameter" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Measurement object supports automatic handling of Array and MultiParameters. When registering these parameters \n", - "the individual components are unpacked and added to the dataset as if they were separate parameters. Lets consider a MultiParamter with array components as the most general case.\n", - "\n", - "First lets use a dummy instrument that produces data as Array and MultiParameters." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "from qcodes.tests.instrument_mocks import DummyChannelInstrument" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [], - "source": [ - "mydummy = DummyChannelInstrument('MyDummy')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This instrument produces 2 Arrays with the names, shapes and setpoints given below." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('this', 'that')" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mydummy.A.dummy_2d_multi_parameter.names" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((5, 3), (5, 3))" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mydummy.A.dummy_2d_multi_parameter.shapes" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(('this_setpoint', 'that_setpoint'), ('this_setpoint', 'that_setpoint'))" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mydummy.A.dummy_2d_multi_parameter.setpoint_names" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([('MyDummy_ChanA_this_setpoint',\n", - " ParamSpec('MyDummy_ChanA_this_setpoint', 'numeric', 'this setpoint', 'this setpointunit', inferred_from=[], depends_on=[])),\n", - " ('MyDummy_ChanA_that_setpoint',\n", - " ParamSpec('MyDummy_ChanA_that_setpoint', 'numeric', 'that setpoint', 'that setpointunit', inferred_from=[], depends_on=[])),\n", - " ('this',\n", - " ParamSpec('this', 'numeric', 'this label', 'this unit', inferred_from=[], depends_on=['MyDummy_ChanA_this_setpoint', 'MyDummy_ChanA_that_setpoint'])),\n", - " ('that',\n", - " ParamSpec('that', 'numeric', 'that label', 'that unit', inferred_from=[], depends_on=['MyDummy_ChanA_this_setpoint', 'MyDummy_ChanA_that_setpoint']))])" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "meas = Measurement()\n", - "\n", - "meas.register_parameter(mydummy.A.dummy_2d_multi_parameter)\n", - "meas.parameters" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When adding the MultiParameter to the measurement we can see that we add each of the individual components as a \n", - "separate parameter." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting experimental run with id: 78\n" - ] - } - ], - "source": [ - "with meas.run() as datasaver:\n", - " datasaver.add_result((mydummy.A.dummy_2d_multi_parameter, mydummy.A.dummy_2d_multi_parameter()))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And when adding the result of a MultiParameter it is automatically unpacked into its components." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "([,\n", - " ],\n", - " [,\n", - " ])" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], + "source": [ + "If your data is on a regular grid it may make sense to view the data as an [XArray](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) Dataset. The Pandas dataframe can be directly exported to xarray" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'].to_xarray()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note however, that XArray is only suited for data that is on regular grid with few or no missing values. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax, abax = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Looking at the above picture, we may decide to sample more finely in the central\n", + "# region\n", + "\n", + "with meas.run() as datasaver:\n", + "\n", + " v1points = np.concatenate((np.linspace(-1, -0.5, 5),\n", + " np.linspace(-0.51, 0.5, 200),\n", + " np.linspace(0.51, 1, 5)))\n", + " v2points = np.concatenate((np.linspace(-1, -0.25, 5),\n", + " np.linspace(-0.26, 0.5, 200),\n", + " np.linspace(0.51, 1, 5)))\n", + " \n", + " for v1 in v1points:\n", + " for v2 in v2points:\n", + " dac.ch1(v1)\n", + " dac.ch2(v2)\n", + " val = dmm.v1.get()\n", + " datasaver.add_result((dac.ch1, v1),\n", + " (dac.ch2, v2),\n", + " (dmm.v1, val))\n", + "\n", + " dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax, cbax = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# or even perform an adaptive sweep... ooohh...\n", + "#\n", + "# This example is a not-very-clever toy model example,\n", + "# but it nicely shows a semi-realistic measurement that the old qc.Loop\n", + "# could not handle\n", + "\n", + "v1_points = np.linspace(-1, 1, 250)\n", + "v2_points = np.linspace(1, -1, 250)\n", + "\n", + "threshold = 0.25\n", + "\n", + "with meas.run() as datasaver:\n", + " \n", + " # Do normal sweeping until the peak is detected\n", + " \n", + " for v2ind, v2 in enumerate(v2_points):\n", + " for v1ind, v1 in enumerate(v1_points):\n", + " dac.ch1(v1)\n", + " dac.ch2(v2)\n", + " val = dmm.v1.get()\n", + " datasaver.add_result((dac.ch1, v1),\n", + " (dac.ch2, v2),\n", + " (dmm.v1, val))\n", + " if val > threshold:\n", + " break\n", + " else:\n", + " continue\n", + " break\n", + " \n", + " print(v1ind, v2ind, val)\n", + " print('-'*10)\n", + " \n", + " # now be more clever, meandering back and forth over the peak\n", + " doneyet = False\n", + " rowdone = False\n", + " v1_step = 1\n", + " while not doneyet:\n", + " v2 = v2_points[v2ind]\n", + " v1 = v1_points[v1ind+v1_step-1]\n", + " dac.ch1(v1)\n", + " dac.ch2(v2)\n", + " val = dmm.v1.get()\n", + " datasaver.add_result((dac.ch1, v1),\n", + " (dac.ch2, v2),\n", + " (dmm.v1, val))\n", + " if val < threshold:\n", + " if rowdone:\n", + " doneyet = True\n", + " v2ind += 1\n", + " v1_step *= -1\n", + " rowdone = True\n", + " else:\n", + " v1ind += v1_step\n", + " rowdone = False\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax, cbax = plot_by_id(dataid)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Random sampling " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We may also chose to sample completely randomly across the phase space" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gauss = gauss_model(0.1, 0.2, 0.25)\n", + "next(gauss)\n", + "\n", + "def measure_gauss(x, y):\n", + " val = gauss.send((x, y))\n", + " next(gauss)\n", + " return val\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "v1_points = np.linspace(-1, 1, 250)\n", + "v2_points = np.linspace(1, -1, 250)\n", + "\n", + "threshold = 0.25\n", + "\n", + "npoints = 5000\n", + "\n", + "with meas.run() as datasaver:\n", + " for i in range(npoints):\n", + " x = 2*(np.random.rand()-.5)\n", + " y = 2*(np.random.rand()-.5)\n", + " z = measure_gauss(x,y)\n", + " datasaver.add_result((dac.ch1, x),\n", + " (dac.ch2, y),\n", + " (dmm.v1, z))\n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax, cbax = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'][0:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unlike the data measured on a grid above all the measured data points have an unique combination of the two dependent parameters. When exporting to XArray NaN's will therefore replace all the missing combinations of `dac_ch1` and `dac_ch2` and the data is unlikely to be useful in this format. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'][0:10].to_xarray()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Optimiser" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An example to show that the algorithm is flexible enough to be used with completely unstructured data such as the output of an downhill simplex optimization. The downhill simplex is somewhat more sensitive to noise and it is important that 'fatol' is set to match the expected noise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.optimize import minimize" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "noise = 0.0005\n", + "\n", + "gauss = gauss_model(0.1, 0.2, 0.25, noise=noise)\n", + "next(gauss)\n", + "\n", + "def measure_gauss(x, y):\n", + " val = gauss.send((x, y))\n", + " next(gauss)\n", + " return val\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x0 = [np.random.rand(), np.random.rand()]\n", + "with meas.run() as datasaver:\n", + " def mycallback(xk):\n", + " datasaver.add_result((dac.ch1, xk[0]),\n", + " (dac.ch2, xk[1]),\n", + " (dmm.v1, measure_gauss(xk[0], xk[1])))\n", + " \n", + " res = minimize(lambda x: -measure_gauss(*x), x0, method='Nelder-Mead', tol=1e-10, \n", + " callback=mycallback, options={'fatol': noise})\n", + " \n", + " run_id = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "res" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ax, cbax = plot_by_id(run_id)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Subscriptions\n", + "\n", + "The Measurement object can also handle subscriptions to the dataset. Subscriptions are really, under the hood, triggers in the underlying SQLite database. Therefore, the subscribers are only called when data is written to the database (which happens every `write_period`).\n", + "\n", + "When making a subscription, two things must be supplied, a function and a mutable state object. The function **MUST** have a call signature of `f(result_list, length, state, **kwargs)`, where result_list is a list of tuples of parameter values inserted in the dataset, length is an integer (the step number of the run), and state is the mutable state object. The function does not need to actually use these arguments, but the call signature must match this.\n", + "\n", + "We show two examples of subscriptions here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Subscription example 1: simple printing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "def print_which_step(results_list, length, state):\n", + " \"\"\"\n", + " This subscriber does not use results_list nor state; it simply\n", + " prints how many results we have added to the database\n", + " \"\"\"\n", + " print(f'The run now holds {length} rows')\n", + " \n", + " \n", + "meas = Measurement()\n", + "meas.register_parameter(dac.ch1)\n", + "meas.register_parameter(dmm.v1, setpoints=(dac.ch1,))\n", + "\n", + "meas.write_period = 1 # We write to the database every 1 second\n", + "\n", + "meas.add_subscriber(print_which_step, state=[])\n", + "\n", + "with meas.run() as datasaver:\n", + " for n in range(10):\n", + " datasaver.add_result((dac.ch1, n), (dmm.v1, n**2))\n", + " print(f'Added points to measurement, step {n}.')\n", + " sleep(0.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Subscription example 2: using the state\n", + "\n", + "We add two subscribers now." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "def get_list_of_first_param(results_list, lenght, state):\n", + " \"\"\"\n", + " Modify the state (a list) to hold all the values for\n", + " the first parameter\n", + " \"\"\"\n", + " param_vals = [parvals[0] for parvals in results_list]\n", + " state += param_vals\n", + " \n", + "meas = Measurement()\n", + "meas.register_parameter(dac.ch1)\n", + "meas.register_parameter(dmm.v1, setpoints=(dac.ch1,))\n", + "\n", + "meas.write_period = 1 # We write to the database every 1 second\n", + "\n", + "first_param_list = []\n", + "\n", + "meas.add_subscriber(print_which_step, state=[])\n", + "meas.add_subscriber(get_list_of_first_param, state=first_param_list)\n", + "\n", + "with meas.run() as datasaver:\n", + " for n in range(10):\n", + " datasaver.add_result((dac.ch1, n), (dmm.v1, n**2))\n", + " print(f'Added points to measurement, step {n}.')\n", + " print(f'First parameter value list: {first_param_list}')\n", + " sleep(0.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## QCoDeS Array and MultiParameter" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Measurement object supports automatic handling of Array and MultiParameters. When registering these parameters \n", + "the individual components are unpacked and added to the dataset as if they were separate parameters. Lets consider a MultiParamter with array components as the most general case.\n", + "\n", + "First lets use a dummy instrument that produces data as Array and MultiParameters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from qcodes.tests.instrument_mocks import DummyChannelInstrument" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mydummy = DummyChannelInstrument('MyDummy')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This instrument produces 2 Arrays with the names, shapes and setpoints given below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mydummy.A.dummy_2d_multi_parameter.names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mydummy.A.dummy_2d_multi_parameter.shapes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mydummy.A.dummy_2d_multi_parameter.setpoint_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "meas = Measurement()\n", + "\n", + "meas.register_parameter(mydummy.A.dummy_2d_multi_parameter)\n", + "meas.parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When adding the MultiParameter to the measurement we can see that we add each of the individual components as a \n", + "separate parameter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with meas.run() as datasaver:\n", + " datasaver.add_result((mydummy.A.dummy_2d_multi_parameter, mydummy.A.dummy_2d_multi_parameter()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And when adding the result of a MultiParameter it is automatically unpacked into its components." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "plot_by_id(datasaver.run_id)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datasaver.dataset.get_data_as_pandas_dataframe()['that']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datasaver.dataset.get_data_as_pandas_dataframe()['that'].to_xarray()" + ] + }, { "cell_type": "code", "execution_count": null, @@ -9013,7 +3599,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.6.8" }, "toc": { "base_numbering": 1, From 4ca776ac603eadbaea9fa7a8975e04ec03f05148 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Tue, 5 Feb 2019 11:19:27 +0100 Subject: [PATCH 708/719] rerun notebook --- .../DataSet/Dataset Context Manager.ipynb | 6613 ++++++++++++++++- 1 file changed, 6362 insertions(+), 251 deletions(-) diff --git a/docs/examples/DataSet/Dataset Context Manager.ipynb b/docs/examples/DataSet/Dataset Context Manager.ipynb index 7e0d985eebf..933f8b76c34 100644 --- a/docs/examples/DataSet/Dataset Context Manager.ipynb +++ b/docs/examples/DataSet/Dataset Context Manager.ipynb @@ -151,7 +151,7 @@ { "data": { "text/plain": [ - "tutorial_exp#no sample#128@C:\\Users\\jenielse/experiments.db\n", + "tutorial_exp#no sample#129@C:\\Users\\jenielse/experiments.db\n", "-----------------------------------------------------------" ] }, @@ -178,7 +178,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 432\n", + "Starting experimental run with id: 443\n", "End of experiment\n" ] } @@ -995,7 +995,7 @@ { "data": { "text/html": [ - "
" + "" ], "text/plain": [ "" @@ -1038,8 +1038,8 @@ { "data": { "text/plain": [ - "{'dmm_v1': {'dmm_v1': array([ 5.10277843, 2.9413283 , 1.60122129, 1.19706838, 0.46107292,\n", - " 0.30048698, 0.16128984, 0.24378436, 0.10619672, -0.15406753]),\n", + "{'dmm_v1': {'dmm_v1': array([ 5.02348283, 2.76737943, 1.54907291, 0.82583077, 0.40845978,\n", + " 0.12302513, 0.1933247 , 0.21199432, 0.04990785, -0.11080111]),\n", " 'dac_ch1': array([ 0. , 2.77777778, 5.55555556, 8.33333333, 11.11111111,\n", " 13.88888889, 16.66666667, 19.44444444, 22.22222222, 25. ])}}" ] @@ -1068,8 +1068,8 @@ { "data": { "text/plain": [ - "{'dmm_v1': {'dmm_v1': array([ 5.10277843, 2.9413283 , 1.60122129, 1.19706838, 0.46107292,\n", - " 0.30048698, 0.16128984, 0.24378436, 0.10619672, -0.15406753]),\n", + "{'dmm_v1': {'dmm_v1': array([ 5.02348283, 2.76737943, 1.54907291, 0.82583077, 0.40845978,\n", + " 0.12302513, 0.1933247 , 0.21199432, 0.04990785, -0.11080111]),\n", " 'dac_ch1': array([ 0. , 2.77777778, 5.55555556, 8.33333333, 11.11111111,\n", " 13.88888889, 16.66666667, 19.44444444, 22.22222222, 25. ])}}" ] @@ -1154,43 +1154,43 @@ " \n", " \n", " 0.000000\n", - " 5.102778\n", + " 5.023483\n", " \n", " \n", " 2.777778\n", - " 2.941328\n", + " 2.767379\n", " \n", " \n", " 5.555556\n", - " 1.601221\n", + " 1.549073\n", " \n", " \n", " 8.333333\n", - " 1.197068\n", + " 0.825831\n", " \n", " \n", " 11.111111\n", - " 0.461073\n", + " 0.408460\n", " \n", " \n", " 13.888889\n", - " 0.300487\n", + " 0.123025\n", " \n", " \n", " 16.666667\n", - " 0.161290\n", + " 0.193325\n", " \n", " \n", " 19.444444\n", - " 0.243784\n", + " 0.211994\n", " \n", " \n", " 22.222222\n", - " 0.106197\n", + " 0.049908\n", " \n", " \n", " 25.000000\n", - " -0.154068\n", + " -0.110801\n", " \n", " \n", "\n", @@ -1199,16 +1199,16 @@ "text/plain": [ " dmm_v1\n", "dac_ch1 \n", - "0.000000 5.102778\n", - "2.777778 2.941328\n", - "5.555556 1.601221\n", - "8.333333 1.197068\n", - "11.111111 0.461073\n", - "13.888889 0.300487\n", - "16.666667 0.161290\n", - "19.444444 0.243784\n", - "22.222222 0.106197\n", - "25.000000 -0.154068" + "0.000000 5.023483\n", + "2.777778 2.767379\n", + "5.555556 1.549073\n", + "8.333333 0.825831\n", + "11.111111 0.408460\n", + "13.888889 0.123025\n", + "16.666667 0.193325\n", + "19.444444 0.211994\n", + "22.222222 0.049908\n", + "25.000000 -0.110801" ] }, "execution_count": 12, @@ -1240,7 +1240,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 433\n", + "Starting experimental run with id: 444\n", "End of experiment\n" ] } @@ -2053,7 +2053,7 @@ { "data": { "text/html": [ - "
" + "" ], "text/plain": [ "" @@ -2078,7 +2078,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 434\n", + "Starting experimental run with id: 445\n", "End of experiment\n" ] } @@ -2895,7 +2895,7 @@ { "data": { "text/html": [ - "
" + "" ], "text/plain": [ "" @@ -2929,7 +2929,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 17, @@ -2969,7 +2969,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -2988,14 +2988,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 435\n" + "Starting experimental run with id: 446\n" ] } ], @@ -3025,11 +3025,107 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
dmm_v1
dac_ch1dac_ch2
-1.0-1.000000-0.000392
-0.9899500.000483
-0.9798990.000108
-0.969849-0.000007
-0.9597990.000011
-0.949749-0.000003
-0.939698-0.000001
-0.929648-0.000001
-0.9195980.000001
-0.909548-0.000002
\n", + "
" + ], + "text/plain": [ + " dmm_v1\n", + "dac_ch1 dac_ch2 \n", + "-1.0 -1.000000 -0.000392\n", + " -0.989950 0.000483\n", + " -0.979899 0.000108\n", + " -0.969849 -0.000007\n", + " -0.959799 0.000011\n", + " -0.949749 -0.000003\n", + " -0.939698 -0.000001\n", + " -0.929648 -0.000001\n", + " -0.919598 0.000001\n", + " -0.909548 -0.000002" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'][0:10]" ] @@ -3043,9 +3139,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Dimensions: (dac_ch1: 200, dac_ch2: 200)\n", + "Coordinates:\n", + " * dac_ch1 (dac_ch1) float64 -1.0 -0.9899 -0.9799 ... 0.9799 0.9899 1.0\n", + " * dac_ch2 (dac_ch2) float64 -1.0 -0.9899 -0.9799 ... 0.9799 0.9899 1.0\n", + "Data variables:\n", + " dmm_v1 (dac_ch1, dac_ch2) float64 -0.0003923 0.0004831 ... 1.039e-05" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'].to_xarray()" ] @@ -3059,195 +3172,3498 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax, abax = plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Looking at the above picture, we may decide to sample more finely in the central\n", - "# region\n", - "\n", - "with meas.run() as datasaver:\n", - "\n", - " v1points = np.concatenate((np.linspace(-1, -0.5, 5),\n", - " np.linspace(-0.51, 0.5, 200),\n", - " np.linspace(0.51, 1, 5)))\n", - " v2points = np.concatenate((np.linspace(-1, -0.25, 5),\n", - " np.linspace(-0.26, 0.5, 200),\n", - " np.linspace(0.51, 1, 5)))\n", - " \n", - " for v1 in v1points:\n", - " for v2 in v2points:\n", - " dac.ch1(v1)\n", - " dac.ch2(v2)\n", - " val = dmm.v1.get()\n", - " datasaver.add_result((dac.ch1, v1),\n", - " (dac.ch2, v2),\n", - " (dmm.v1, val))\n", - "\n", - " dataid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax, cbax = plot_by_id(dataid)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# or even perform an adaptive sweep... ooohh...\n", - "#\n", - "# This example is a not-very-clever toy model example,\n", - "# but it nicely shows a semi-realistic measurement that the old qc.Loop\n", - "# could not handle\n", - "\n", - "v1_points = np.linspace(-1, 1, 250)\n", - "v2_points = np.linspace(1, -1, 250)\n", - "\n", - "threshold = 0.25\n", - "\n", - "with meas.run() as datasaver:\n", - " \n", - " # Do normal sweeping until the peak is detected\n", - " \n", - " for v2ind, v2 in enumerate(v2_points):\n", - " for v1ind, v1 in enumerate(v1_points):\n", - " dac.ch1(v1)\n", - " dac.ch2(v2)\n", - " val = dmm.v1.get()\n", - " datasaver.add_result((dac.ch1, v1),\n", - " (dac.ch2, v2),\n", - " (dmm.v1, val))\n", - " if val > threshold:\n", - " break\n", - " else:\n", - " continue\n", - " break\n", - " \n", - " print(v1ind, v2ind, val)\n", - " print('-'*10)\n", - " \n", - " # now be more clever, meandering back and forth over the peak\n", - " doneyet = False\n", - " rowdone = False\n", - " v1_step = 1\n", - " while not doneyet:\n", - " v2 = v2_points[v2ind]\n", - " v1 = v1_points[v1ind+v1_step-1]\n", - " dac.ch1(v1)\n", - " dac.ch2(v2)\n", - " val = dmm.v1.get()\n", - " datasaver.add_result((dac.ch1, v1),\n", - " (dac.ch2, v2),\n", - " (dmm.v1, val))\n", - " if val < threshold:\n", - " if rowdone:\n", - " doneyet = True\n", - " v2ind += 1\n", - " v1_step *= -1\n", - " rowdone = True\n", - " else:\n", - " v1ind += v1_step\n", - " rowdone = False\n", - " \n", - "dataid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ax, cbax = plot_by_id(dataid)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## Random sampling " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We may also chose to sample completely randomly across the phase space" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "gauss = gauss_model(0.1, 0.2, 0.25)\n", - "next(gauss)\n", - "\n", - "def measure_gauss(x, y):\n", - " val = gauss.send((x, y))\n", - " next(gauss)\n", - " return val\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "v1_points = np.linspace(-1, 1, 250)\n", - "v2_points = np.linspace(1, -1, 250)\n", - "\n", - "threshold = 0.25\n", - "\n", - "npoints = 5000\n", - "\n", - "with meas.run() as datasaver:\n", - " for i in range(npoints):\n", - " x = 2*(np.random.rand()-.5)\n", - " y = 2*(np.random.rand()-.5)\n", - " z = measure_gauss(x,y)\n", - " datasaver.add_result((dac.ch1, x),\n", - " (dac.ch2, y),\n", - " (dmm.v1, z))\n", - "dataid = datasaver.run_id" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ax, cbax = plot_by_id(dataid)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 448\n", + "130 46 0.25089416830953565\n", + "----------\n" + ] + } + ], + "source": [ + "# or even perform an adaptive sweep... ooohh...\n", + "#\n", + "# This example is a not-very-clever toy model example,\n", + "# but it nicely shows a semi-realistic measurement that the old qc.Loop\n", + "# could not handle\n", + "\n", + "v1_points = np.linspace(-1, 1, 250)\n", + "v2_points = np.linspace(1, -1, 250)\n", + "\n", + "threshold = 0.25\n", + "\n", + "with meas.run() as datasaver:\n", + " \n", + " # Do normal sweeping until the peak is detected\n", + " \n", + " for v2ind, v2 in enumerate(v2_points):\n", + " for v1ind, v1 in enumerate(v1_points):\n", + " dac.ch1(v1)\n", + " dac.ch2(v2)\n", + " val = dmm.v1.get()\n", + " datasaver.add_result((dac.ch1, v1),\n", + " (dac.ch2, v2),\n", + " (dmm.v1, val))\n", + " if val > threshold:\n", + " break\n", + " else:\n", + " continue\n", + " break\n", + " \n", + " print(v1ind, v2ind, val)\n", + " print('-'*10)\n", + " \n", + " # now be more clever, meandering back and forth over the peak\n", + " doneyet = False\n", + " rowdone = False\n", + " v1_step = 1\n", + " while not doneyet:\n", + " v2 = v2_points[v2ind]\n", + " v1 = v1_points[v1ind+v1_step-1]\n", + " dac.ch1(v1)\n", + " dac.ch2(v2)\n", + " val = dmm.v1.get()\n", + " datasaver.add_result((dac.ch1, v1),\n", + " (dac.ch2, v2),\n", + " (dmm.v1, val))\n", + " if val < threshold:\n", + " if rowdone:\n", + " doneyet = True\n", + " v2ind += 1\n", + " v1_step *= -1\n", + " rowdone = True\n", + " else:\n", + " v1ind += v1_step\n", + " rowdone = False\n", + " \n", + "dataid = datasaver.run_id" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "ax, cbax = plot_by_id(dataid)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
dmm_v1
dac_ch1dac_ch2
-0.2095030.6287230.121980
-0.7440030.4317780.002514
0.7738140.3842530.022878
0.072686-0.9861150.000041
-0.7470010.3431670.003133
-0.762881-0.3229060.000334
0.9474560.1920680.003616
-0.670000-0.5329650.000132
-0.403736-0.1185550.066083
0.2783100.8859720.020366
\n", + "
" + ], + "text/plain": [ + " dmm_v1\n", + "dac_ch1 dac_ch2 \n", + "-0.209503 0.628723 0.121980\n", + "-0.744003 0.431778 0.002514\n", + " 0.773814 0.384253 0.022878\n", + " 0.072686 -0.986115 0.000041\n", + "-0.747001 0.343167 0.003133\n", + "-0.762881 -0.322906 0.000334\n", + " 0.947456 0.192068 0.003616\n", + "-0.670000 -0.532965 0.000132\n", + "-0.403736 -0.118555 0.066083\n", + " 0.278310 0.885972 0.020366" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'][0:10]" ] @@ -3261,9 +6677,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "Dimensions: (dac_ch1: 5000, dac_ch2: 5000)\n", + "Coordinates:\n", + " * dac_ch1 (dac_ch1) float64 -0.9991 -0.9979 -0.9976 ... 0.9982 0.9985 0.9987\n", + " * dac_ch2 (dac_ch2) float64 -0.999 -0.9989 -0.9987 ... 0.9968 0.9971 0.9977\n", + "Data variables:\n", + " dmm_v1 (dac_ch1, dac_ch2) float64 nan nan nan nan nan ... nan nan nan nan" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1'][0:10].to_xarray()" ] @@ -3284,7 +6717,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -3293,7 +6726,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -3310,9 +6743,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 450\n" + ] + } + ], "source": [ "x0 = [np.random.rand(), np.random.rand()]\n", "with meas.run() as datasaver:\n", @@ -3329,18 +6770,831 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + " final_simplex: (array([[0.99812801, 0.64445492],\n", + " [0.99812801, 0.64445492],\n", + " [0.99812801, 0.64445492]]), array([-0.00083562, -0.00036764, -0.00036764]))\n", + " fun: -0.0008356242479310768\n", + " message: 'Optimization terminated successfully.'\n", + " nfev: 123\n", + " nit: 33\n", + " status: 0\n", + " success: True\n", + " x: array([0.99812801, 0.64445492])" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1.reset_index().plot.scatter('dac_ch1', 'dac_ch2', c='dmm_v1')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Merging two dataframes with the same labels is fairly simple." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.concat([df1, df2], sort=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(2,2)\n", + "xaDataArray.plot(ax=ax[0,0])\n", + "xaDataArray.mean(dim='dac_ch1').plot(ax=ax[1,0])\n", + "xaDataArray.mean(dim='dac_ch2').plot(ax=ax[0,1])\n", + "xaDataArray[[200]].plot(ax=ax[1,1])\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 8f18a331962fafa84f2920480ea17a5e39ba64a6 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 6 Feb 2019 13:07:04 +0100 Subject: [PATCH 712/719] Update notebooks with more text --- .../DataSet/Dataset Context Manager.ipynb | 329 ++++++++++-------- .../Working-With-Pandas-and-XArray.ipynb | 205 ++++++----- 2 files changed, 295 insertions(+), 239 deletions(-) diff --git a/docs/examples/DataSet/Dataset Context Manager.ipynb b/docs/examples/DataSet/Dataset Context Manager.ipynb index 1935382f8d0..07468f95aa5 100644 --- a/docs/examples/DataSet/Dataset Context Manager.ipynb +++ b/docs/examples/DataSet/Dataset Context Manager.ipynb @@ -151,7 +151,7 @@ { "data": { "text/plain": [ - "tutorial_exp#no sample#129@C:\\Users\\jenielse/experiments.db\n", + "tutorial_exp#no sample#137@C:\\Users\\jenielse/experiments.db\n", "-----------------------------------------------------------" ] }, @@ -178,7 +178,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 443\n", + "Starting experimental run with id: 480\n", "End of experiment\n" ] } @@ -995,7 +995,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -1038,8 +1038,8 @@ { "data": { "text/plain": [ - "{'dmm_v1': {'dmm_v1': array([ 5.02348283, 2.76737943, 1.54907291, 0.82583077, 0.40845978,\n", - " 0.12302513, 0.1933247 , 0.21199432, 0.04990785, -0.11080111]),\n", + "{'dmm_v1': {'dmm_v1': array([4.84812039, 2.85192992, 1.77006663, 1.16772991, 0.70324665,\n", + " 0.18518276, 0.25720134, 0.07539374, 0.01103977, 0.02022141]),\n", " 'dac_ch1': array([ 0. , 2.77777778, 5.55555556, 8.33333333, 11.11111111,\n", " 13.88888889, 16.66666667, 19.44444444, 22.22222222, 25. ])}}" ] @@ -1068,8 +1068,8 @@ { "data": { "text/plain": [ - "{'dmm_v1': {'dmm_v1': array([ 5.02348283, 2.76737943, 1.54907291, 0.82583077, 0.40845978,\n", - " 0.12302513, 0.1933247 , 0.21199432, 0.04990785, -0.11080111]),\n", + "{'dmm_v1': {'dmm_v1': array([4.84812039, 2.85192992, 1.77006663, 1.16772991, 0.70324665,\n", + " 0.18518276, 0.25720134, 0.07539374, 0.01103977, 0.02022141]),\n", " 'dac_ch1': array([ 0. , 2.77777778, 5.55555556, 8.33333333, 11.11111111,\n", " 13.88888889, 16.66666667, 19.44444444, 22.22222222, 25. ])}}" ] @@ -1115,7 +1115,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The data can also be exported as one or more [Pandas](https://pandas.pydata.org/) dataframes. The dataframes are returns as a dict from measured parameters to dataframes." + "The data can also be exported as one or more [Pandas](https://pandas.pydata.org/) DataFrames. The DataFrames are returns as a dict from measured parameters to DataFrames." ] }, { @@ -1154,43 +1154,43 @@ " \n", " \n", " 0.000000\n", - " 5.023483\n", + " 4.848120\n", " \n", " \n", " 2.777778\n", - " 2.767379\n", + " 2.851930\n", " \n", " \n", " 5.555556\n", - " 1.549073\n", + " 1.770067\n", " \n", " \n", " 8.333333\n", - " 0.825831\n", + " 1.167730\n", " \n", " \n", " 11.111111\n", - " 0.408460\n", + " 0.703247\n", " \n", " \n", " 13.888889\n", - " 0.123025\n", + " 0.185183\n", " \n", " \n", " 16.666667\n", - " 0.193325\n", + " 0.257201\n", " \n", " \n", " 19.444444\n", - " 0.211994\n", + " 0.075394\n", " \n", " \n", " 22.222222\n", - " 0.049908\n", + " 0.011040\n", " \n", " \n", " 25.000000\n", - " -0.110801\n", + " 0.020221\n", " \n", " \n", "\n", @@ -1199,16 +1199,16 @@ "text/plain": [ " dmm_v1\n", "dac_ch1 \n", - "0.000000 5.023483\n", - "2.777778 2.767379\n", - "5.555556 1.549073\n", - "8.333333 0.825831\n", - "11.111111 0.408460\n", - "13.888889 0.123025\n", - "16.666667 0.193325\n", - "19.444444 0.211994\n", - "22.222222 0.049908\n", - "25.000000 -0.110801" + "0.000000 4.848120\n", + "2.777778 2.851930\n", + "5.555556 1.770067\n", + "8.333333 1.167730\n", + "11.111111 0.703247\n", + "13.888889 0.185183\n", + "16.666667 0.257201\n", + "19.444444 0.075394\n", + "22.222222 0.011040\n", + "25.000000 0.020221" ] }, "execution_count": 12, @@ -1220,6 +1220,13 @@ "datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1']" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For more details about using Pandas and XArray see [Working With Pandas and XArray](./Working-With-Pandas-and-XArray.ipynb)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1240,7 +1247,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 444\n", + "Starting experimental run with id: 481\n", "End of experiment\n" ] } @@ -2053,7 +2060,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2078,7 +2085,7 @@ "text": [ "Starting the measurement\n", "Doing stuff with the following two instruments: , \n", - "Starting experimental run with id: 445\n", + "Starting experimental run with id: 482\n", "End of experiment\n" ] } @@ -2895,7 +2902,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2929,7 +2936,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 17, @@ -2995,7 +3002,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 446\n" + "Starting experimental run with id: 483\n" ] } ], @@ -3020,7 +3027,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "When exporting a two or higher dimensional dataset as a Pandas dataframe a [MultiIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) is used to index the measured parameter based on all the dependencies" + "When exporting a two or higher dimensional datasets as a Pandas DataFrame a [MultiIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) is used to index the measured parameter based on all the dependencies" ] }, { @@ -3064,43 +3071,43 @@ " \n", " -1.0\n", " -1.000000\n", - " -0.000392\n", + " 0.000369\n", " \n", " \n", " -0.989950\n", - " 0.000483\n", + " -0.000470\n", " \n", " \n", " -0.979899\n", - " 0.000108\n", + " -0.000244\n", " \n", " \n", " -0.969849\n", - " -0.000007\n", + " 0.000091\n", " \n", " \n", " -0.959799\n", - " 0.000011\n", + " -0.000067\n", " \n", " \n", " -0.949749\n", - " -0.000003\n", + " 0.000061\n", " \n", " \n", " -0.939698\n", - " -0.000001\n", + " 0.000071\n", " \n", " \n", " -0.929648\n", - " -0.000001\n", + " -0.000088\n", " \n", " \n", " -0.919598\n", - " 0.000001\n", + " 0.000148\n", " \n", " \n", " -0.909548\n", - " -0.000002\n", + " -0.000252\n", " \n", " \n", "\n", @@ -3109,16 +3116,16 @@ "text/plain": [ " dmm_v1\n", "dac_ch1 dac_ch2 \n", - "-1.0 -1.000000 -0.000392\n", - " -0.989950 0.000483\n", - " -0.979899 0.000108\n", - " -0.969849 -0.000007\n", - " -0.959799 0.000011\n", - " -0.949749 -0.000003\n", - " -0.939698 -0.000001\n", - " -0.929648 -0.000001\n", - " -0.919598 0.000001\n", - " -0.909548 -0.000002" + "-1.0 -1.000000 0.000369\n", + " -0.989950 -0.000470\n", + " -0.979899 -0.000244\n", + " -0.969849 0.000091\n", + " -0.959799 -0.000067\n", + " -0.949749 0.000061\n", + " -0.939698 0.000071\n", + " -0.929648 -0.000088\n", + " -0.919598 0.000148\n", + " -0.909548 -0.000252" ] }, "execution_count": 21, @@ -3134,7 +3141,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If your data is on a regular grid it may make sense to view the data as an [XArray](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) Dataset. The Pandas dataframe can be directly exported to xarray" + "If your data is on a regular grid it may make sense to view the data as an [XArray](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) Dataset. The Pandas DataFrame can be directly exported to a XArray Dataset." ] }, { @@ -3151,7 +3158,7 @@ " * dac_ch1 (dac_ch1) float64 -1.0 -0.9899 -0.9799 ... 0.9799 0.9899 1.0\n", " * dac_ch2 (dac_ch2) float64 -1.0 -0.9899 -0.9799 ... 0.9799 0.9899 1.0\n", "Data variables:\n", - " dmm_v1 (dac_ch1, dac_ch2) float64 -0.0003923 0.0004831 ... 1.039e-05" + " dmm_v1 (dac_ch1, dac_ch2) float64 0.0003689 -0.0004697 ... 1.039e-05" ] }, "execution_count": 22, @@ -3167,7 +3174,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Note however, that XArray is only suited for data that is on regular grid with few or no missing values. " + "Note however, that XArray is only suited for data that is on rectangular grid with few or no missing values. " ] }, { @@ -3958,7 +3965,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -3981,7 +3988,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 447\n" + "Starting experimental run with id: 484\n" ] } ], @@ -4798,7 +4805,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -4821,7 +4828,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 448\n", + "Starting experimental run with id: 485\n", "130 46 0.25089416830953565\n", "----------\n" ] @@ -5674,7 +5681,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -5729,7 +5736,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 449\n" + "Starting experimental run with id: 486\n" ] } ], @@ -6540,7 +6547,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -6591,54 +6598,54 @@ " \n", " \n", " \n", - " -0.209503\n", - " 0.628723\n", - " 0.121980\n", + " -0.257408\n", + " -0.880324\n", + " 0.000129\n", " \n", " \n", - " -0.744003\n", - " 0.431778\n", - " 0.002514\n", + " -0.708778\n", + " -0.054650\n", + " 0.003752\n", " \n", " \n", - " 0.773814\n", - " 0.384253\n", - " 0.022878\n", + " -0.317528\n", + " -0.409047\n", + " 0.014472\n", " \n", " \n", - " 0.072686\n", - " -0.986115\n", - " 0.000041\n", + " 0.754722\n", + " -0.727091\n", + " 0.000023\n", " \n", " \n", - " -0.747001\n", - " 0.343167\n", - " 0.003133\n", + " 0.076441\n", + " -0.934705\n", + " 0.000027\n", " \n", " \n", - " -0.762881\n", - " -0.322906\n", - " 0.000334\n", + " 0.026166\n", + " 0.463654\n", + " 0.622060\n", " \n", " \n", - " 0.947456\n", - " 0.192068\n", - " 0.003616\n", + " 0.796483\n", + " 0.268140\n", + " 0.022531\n", " \n", " \n", - " -0.670000\n", - " -0.532965\n", - " 0.000132\n", + " -0.378744\n", + " -0.525162\n", + " 0.002697\n", " \n", " \n", - " -0.403736\n", - " -0.118555\n", - " 0.066083\n", + " 0.458012\n", + " -0.216361\n", + " 0.101547\n", " \n", " \n", - " 0.278310\n", - " 0.885972\n", - " 0.020366\n", + " -0.642956\n", + " -0.386786\n", + " 0.000871\n", " \n", " \n", "\n", @@ -6647,16 +6654,16 @@ "text/plain": [ " dmm_v1\n", "dac_ch1 dac_ch2 \n", - "-0.209503 0.628723 0.121980\n", - "-0.744003 0.431778 0.002514\n", - " 0.773814 0.384253 0.022878\n", - " 0.072686 -0.986115 0.000041\n", - "-0.747001 0.343167 0.003133\n", - "-0.762881 -0.322906 0.000334\n", - " 0.947456 0.192068 0.003616\n", - "-0.670000 -0.532965 0.000132\n", - "-0.403736 -0.118555 0.066083\n", - " 0.278310 0.885972 0.020366" + "-0.257408 -0.880324 0.000129\n", + "-0.708778 -0.054650 0.003752\n", + "-0.317528 -0.409047 0.014472\n", + " 0.754722 -0.727091 0.000023\n", + " 0.076441 -0.934705 0.000027\n", + " 0.026166 0.463654 0.622060\n", + " 0.796483 0.268140 0.022531\n", + "-0.378744 -0.525162 0.002697\n", + " 0.458012 -0.216361 0.101547\n", + "-0.642956 -0.386786 0.000871" ] }, "execution_count": 31, @@ -6686,8 +6693,8 @@ "\n", "Dimensions: (dac_ch1: 5000, dac_ch2: 5000)\n", "Coordinates:\n", - " * dac_ch1 (dac_ch1) float64 -0.9991 -0.9979 -0.9976 ... 0.9982 0.9985 0.9987\n", - " * dac_ch2 (dac_ch2) float64 -0.999 -0.9989 -0.9987 ... 0.9968 0.9971 0.9977\n", + " * dac_ch1 (dac_ch1) float64 -0.9997 -0.9995 -0.9994 ... 0.9991 0.9992 0.9998\n", + " * dac_ch2 (dac_ch2) float64 -0.9999 -0.9993 -0.9993 ... 0.999 0.9999 1.0\n", "Data variables:\n", " dmm_v1 (dac_ch1, dac_ch2) float64 nan nan nan nan nan ... nan nan nan nan" ] @@ -6750,7 +6757,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 450\n" + "Starting experimental run with id: 487\n" ] } ], @@ -6776,16 +6783,16 @@ { "data": { "text/plain": [ - " final_simplex: (array([[0.99812801, 0.64445492],\n", - " [0.99812801, 0.64445492],\n", - " [0.99812801, 0.64445492]]), array([-0.00083562, -0.00036764, -0.00036764]))\n", - " fun: -0.0008356242479310768\n", + " final_simplex: (array([[0.1, 0.2],\n", + " [0.1, 0.2],\n", + " [0.1, 0.2]]), array([-1.13314845, -1.13314845, -1.13314845]))\n", + " fun: -1.1331484530668263\n", " message: 'Optimization terminated successfully.'\n", - " nfev: 123\n", - " nit: 33\n", + " nfev: 153\n", + " nit: 75\n", " status: 0\n", " success: True\n", - " x: array([0.99812801, 0.64445492])" + " x: array([0.1, 0.2])" ] }, "execution_count": 36, @@ -7585,7 +7592,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -7593,6 +7600,18 @@ }, "metadata": {}, "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2019-02-06 12:40:45,288 ¦ py.warnings ¦ WARNING ¦ warnings ¦ _showwarnmsg ¦ 99 ¦ c:\\users\\jenielse\\source\\repos\\qcodes\\qcodes\\dataset\\data_export.py:131: RuntimeWarning: divide by zero encountered in true_divide\n", + " remainders = np.mod(steps[1:]/steps[0], 1)\n", + "\n", + "2019-02-06 12:40:45,296 ¦ py.warnings ¦ WARNING ¦ warnings ¦ _showwarnmsg ¦ 99 ¦ c:\\users\\jenielse\\source\\repos\\qcodes\\qcodes\\dataset\\data_export.py:131: RuntimeWarning: invalid value encountered in remainder\n", + " remainders = np.mod(steps[1:]/steps[0], 1)\n", + "\n" + ] } ], "source": [ @@ -7630,21 +7649,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 451\n", + "Starting experimental run with id: 488\n", "Added points to measurement, step 0.\n", "Added points to measurement, step 1.\n", "The run now holds 3 rows\n", "Added points to measurement, step 2.\n", "Added points to measurement, step 3.\n", + "The run now holds 5 rows\n", "Added points to measurement, step 4.\n", - "The run now holds 6 rows\n", "Added points to measurement, step 5.\n", + "The run now holds 6 rows\n", "Added points to measurement, step 6.\n", - "The run now holds 8 rows\n", "Added points to measurement, step 7.\n", "Added points to measurement, step 8.\n", - "Added points to measurement, step 9.\n", "The run now holds 10 rows\n", + "Added points to measurement, step 9.\n", "The run now holds 10 rows\n", "The run now holds 10 rows\n" ] @@ -7694,7 +7713,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 452\n", + "Starting experimental run with id: 489\n", "Added points to measurement, step 0.\n", "First parameter value list: []\n", "Added points to measurement, step 1.\n", @@ -7704,21 +7723,22 @@ "First parameter value list: [0, 1, 2]\n", "Added points to measurement, step 3.\n", "First parameter value list: [0, 1, 2]\n", - "Added points to measurement, step 4.\n", - "First parameter value list: [0, 1, 2]\n", "The run now holds 4 rows\n", + "Added points to measurement, step 4.\n", + "First parameter value list: [0, 1, 2, 3, 4]\n", "Added points to measurement, step 5.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5]\n", + "First parameter value list: [0, 1, 2, 3, 4]\n", + "The run now holds 6 rows\n", "Added points to measurement, step 6.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5]\n", - "The run now holds 7 rows\n", + "First parameter value list: [0, 1, 2, 3, 4, 5, 6]\n", "Added points to measurement, step 7.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7]\n", + "First parameter value list: [0, 1, 2, 3, 4, 5, 6]\n", + "The run now holds 8 rows\n", "Added points to measurement, step 8.\n", "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7]\n", - "The run now holds 9 rows\n", "Added points to measurement, step 9.\n", - "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7, 8]\n", + "First parameter value list: [0, 1, 2, 3, 4, 5, 6, 7]\n", + "The run now holds 10 rows\n", "The run now holds 10 rows\n", "The run now holds 10 rows\n" ] @@ -7903,7 +7923,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 453\n" + "Starting experimental run with id: 490\n" ] } ], @@ -8707,7 +8727,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -9499,7 +9519,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -9511,10 +9531,10 @@ { "data": { "text/plain": [ - "([,\n", - " ],\n", - " [,\n", - " ])" + "([,\n", + " ],\n", + " [,\n", + " ])" ] }, "execution_count": 47, @@ -9528,7 +9548,29 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'that': {'that': array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),\n", + " 'MyDummy_ChanA_this_setpoint': array([5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]),\n", + " 'MyDummy_ChanA_that_setpoint': array([ 9, 10, 11, 9, 10, 11, 9, 10, 11, 9, 10, 11, 9, 10, 11])}}" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "datasaver.dataset.get_parameter_data('that')" + ] + }, + { + "cell_type": "code", + "execution_count": 49, "metadata": {}, "outputs": [ { @@ -9651,7 +9693,7 @@ " 11 1" ] }, - "execution_count": 48, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -9662,7 +9704,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -9677,7 +9719,7 @@ " that (MyDummy_ChanA_this_setpoint, MyDummy_ChanA_that_setpoint) int32 1 ... 1" ] }, - "execution_count": 49, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -9685,13 +9727,6 @@ "source": [ "datasaver.dataset.get_data_as_pandas_dataframe()['that'].to_xarray()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb b/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb index c5a53f66204..f8145fbb8fb 100644 --- a/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb +++ b/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb @@ -7,6 +7,27 @@ "# Working with Pandas and XArray" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook is demonstrates how Pandas and XArray can be used to work with the QCoDeS Dataset. It is not meant as a general introduction to Pandas and XAarray. We refer to the official documentation for [Pandas](https://pandas.pydata.org/) and [XArray](http://xarray.pydata.org/en/stable/) for this. This notebook requires that both Pandas and XArray is installed." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we borrow an example from the Dataset notebook to have some data to work with. We split the measurement in two so we can try merging it with Pandas." + ] + }, { "cell_type": "code", "execution_count": 1, @@ -43,13 +64,6 @@ "qc.logger.start_all_logging()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we borrow an example from the Dataset notebook to have some data to work with. We split the measurement in two so we can try merging it." - ] - }, { "cell_type": "code", "execution_count": 2, @@ -70,7 +84,7 @@ { "data": { "text/plain": [ - "tutorial_exp#no sample#134@C:\\Users\\jenielse/experiments.db\n", + "tutorial_exp#no sample#136@C:\\Users\\jenielse/experiments.db\n", "-----------------------------------------------------------" ] }, @@ -92,7 +106,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 4, @@ -153,7 +167,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "First half:" + "We then perform a very basic experiment. To be able to demonstrate merging of datasets in Pandas we will perform the measurement in two parts." ] }, { @@ -165,7 +179,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 474\n" + "Starting experimental run with id: 478\n" ] } ], @@ -187,13 +201,6 @@ "df1 = datasaver.dataset.get_data_as_pandas_dataframe()['dmm_v1']" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Second half:" - ] - }, { "cell_type": "code", "execution_count": 8, @@ -203,7 +210,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 475\n" + "Starting experimental run with id: 479\n" ] } ], @@ -229,7 +236,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Lets first inspect the Pandas dataframe" + "`get_data_as_pandas_dataframe` returns the data as a dict from measured (dependent) parameters to DataFrames. Here we are only interested in the dataframe of a single parameter so we selec that from the dict." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Working with Pandas" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets first inspect the Pandas DataFrame. Note how both dependent variables are used for the index. Pandas refers to this as a [MultiIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html)" ] }, { @@ -271,61 +292,61 @@ " \n", " -1.0\n", " -1.00\n", - " -0.000372\n", + " -5.073949e-04\n", " \n", " \n", " -0.99\n", - " 0.000267\n", + " 7.058781e-04\n", " \n", " \n", " -0.98\n", - " 0.000217\n", + " 9.828259e-05\n", " \n", " \n", " -0.97\n", - " 0.000015\n", + " -1.795980e-04\n", " \n", " \n", " -0.96\n", - " 0.000023\n", + " -3.483247e-04\n", " \n", " \n", " -0.95\n", - " -0.000037\n", + " -7.151994e-05\n", " \n", " \n", " -0.94\n", - " -0.000004\n", + " 3.202385e-05\n", " \n", " \n", " -0.93\n", - " 0.000004\n", + " -8.596531e-07\n", " \n", " \n", " -0.92\n", - " 0.000003\n", + " 1.450387e-06\n", " \n", " \n", " -0.91\n", - " -0.000002\n", + " 4.319205e-07\n", " \n", " \n", "\n", "
" ], "text/plain": [ - " dmm_v1\n", - "dac_ch1 dac_ch2 \n", - "-1.0 -1.00 -0.000372\n", - " -0.99 0.000267\n", - " -0.98 0.000217\n", - " -0.97 0.000015\n", - " -0.96 0.000023\n", - " -0.95 -0.000037\n", - " -0.94 -0.000004\n", - " -0.93 0.000004\n", - " -0.92 0.000003\n", - " -0.91 -0.000002" + " dmm_v1\n", + "dac_ch1 dac_ch2 \n", + "-1.0 -1.00 -5.073949e-04\n", + " -0.99 7.058781e-04\n", + " -0.98 9.828259e-05\n", + " -0.97 -1.795980e-04\n", + " -0.96 -3.483247e-04\n", + " -0.95 -7.151994e-05\n", + " -0.94 3.202385e-05\n", + " -0.93 -8.596531e-07\n", + " -0.92 1.450387e-06\n", + " -0.91 4.319205e-07" ] }, "execution_count": 9, @@ -341,7 +362,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We can also reset the index to return a simpler view where all datapoints are simply indexed by a running counter. This will come in handy just below." + "We can also reset the index to return a simpler view where all data points are simply indexed by a running counter. As we shall see below this can be needed in some situations." ] }, { @@ -380,78 +401,78 @@ " 0\n", " -1.0\n", " -1.00\n", - " -0.000372\n", + " -5.073949e-04\n", " \n", " \n", " 1\n", " -1.0\n", " -0.99\n", - " 0.000267\n", + " 7.058781e-04\n", " \n", " \n", " 2\n", " -1.0\n", " -0.98\n", - " 0.000217\n", + " 9.828259e-05\n", " \n", " \n", " 3\n", " -1.0\n", " -0.97\n", - " 0.000015\n", + " -1.795980e-04\n", " \n", " \n", " 4\n", " -1.0\n", " -0.96\n", - " 0.000023\n", + " -3.483247e-04\n", " \n", " \n", " 5\n", " -1.0\n", " -0.95\n", - " -0.000037\n", + " -7.151994e-05\n", " \n", " \n", " 6\n", " -1.0\n", " -0.94\n", - " -0.000004\n", + " 3.202385e-05\n", " \n", " \n", " 7\n", " -1.0\n", " -0.93\n", - " 0.000004\n", + " -8.596531e-07\n", " \n", " \n", " 8\n", " -1.0\n", " -0.92\n", - " 0.000003\n", + " 1.450387e-06\n", " \n", " \n", " 9\n", " -1.0\n", " -0.91\n", - " -0.000002\n", + " 4.319205e-07\n", " \n", " \n", "\n", "
" ], "text/plain": [ - " dac_ch1 dac_ch2 dmm_v1\n", - "0 -1.0 -1.00 -0.000372\n", - "1 -1.0 -0.99 0.000267\n", - "2 -1.0 -0.98 0.000217\n", - "3 -1.0 -0.97 0.000015\n", - "4 -1.0 -0.96 0.000023\n", - "5 -1.0 -0.95 -0.000037\n", - "6 -1.0 -0.94 -0.000004\n", - "7 -1.0 -0.93 0.000004\n", - "8 -1.0 -0.92 0.000003\n", - "9 -1.0 -0.91 -0.000002" + " dac_ch1 dac_ch2 dmm_v1\n", + "0 -1.0 -1.00 -5.073949e-04\n", + "1 -1.0 -0.99 7.058781e-04\n", + "2 -1.0 -0.98 9.828259e-05\n", + "3 -1.0 -0.97 -1.795980e-04\n", + "4 -1.0 -0.96 -3.483247e-04\n", + "5 -1.0 -0.95 -7.151994e-05\n", + "6 -1.0 -0.94 3.202385e-05\n", + "7 -1.0 -0.93 -8.596531e-07\n", + "8 -1.0 -0.92 1.450387e-06\n", + "9 -1.0 -0.91 4.319205e-07" ] }, "execution_count": 10, @@ -467,14 +488,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Pandas has build in support for various forms of plotting. This does however, not support MultiIndex at the moment but we can use `reset_index` to make the data available for plotting." + "Pandas has build in support for various forms of plotting. This does however, not support MultiIndex at the moment so we use `reset_index` to make the data available for plotting." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { - "scrolled": true + "scrolled": false }, "outputs": [ { @@ -1260,7 +1281,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -1272,7 +1293,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 11, @@ -2090,7 +2111,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2102,7 +2123,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 13, @@ -2118,7 +2139,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "It is also possible to select a subset of data from the datframe based on the x and y values" + "It is also possible to select a subset of data from the datframe based on the x and y values." ] }, { @@ -2160,19 +2181,19 @@ " \n", " -1.000\n", " -1.00\n", - " -3.724157e-04\n", + " -5.073949e-04\n", " \n", " \n", " -0.99\n", - " 2.674091e-04\n", + " 7.058781e-04\n", " \n", " \n", " -0.98\n", - " 2.168524e-04\n", + " 9.828259e-05\n", " \n", " \n", " -0.97\n", - " 1.543205e-05\n", + " -1.795980e-04\n", " \n", " \n", " -0.995\n", @@ -2351,10 +2372,10 @@ "text/plain": [ " dmm_v1\n", "dac_ch1 dac_ch2 \n", - "-1.000 -1.00 -3.724157e-04\n", - " -0.99 2.674091e-04\n", - " -0.98 2.168524e-04\n", - " -0.97 1.543205e-05\n", + "-1.000 -1.00 -5.073949e-04\n", + " -0.99 7.058781e-04\n", + " -0.98 9.828259e-05\n", + " -0.97 -1.795980e-04\n", "-0.995 -1.00 7.680241e-10\n", " -0.99 9.298480e-10\n", " -0.98 1.123969e-09\n", @@ -2410,21 +2431,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## XArray" + "## Working with XArray" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "In many cases when working with data on a grid it may be more convenient to export the data to a [XArray](http://xarray.pydata.org) Dataset or DataArray" + "In many cases when working with data on a rectangular grids it may be more convenient to export the data to a [XArray](http://xarray.pydata.org) Dataset or DataArray" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The Pandas DataSet can be directly converted to a XArray DataSet:" + "The Pandas DataSet can be directly converted to a XArray [Dataset](http://xarray.pydata.org/en/stable/data-structures.html?#dataset):" ] }, { @@ -2450,7 +2471,7 @@ " * dac_ch1 (dac_ch1) float64 -1.0 -0.995 -0.99 -0.985 ... 0.985 0.99 0.995 1.0\n", " * dac_ch2 (dac_ch2) float64 -1.0 -0.99 -0.98 -0.97 ... 0.97 0.98 0.99 1.0\n", "Data variables:\n", - " dmm_v1 (dac_ch1, dac_ch2) float64 -0.0003724 0.0002674 ... 1.039e-05" + " dmm_v1 (dac_ch1, dac_ch2) float64 -0.0005074 0.0007059 ... 1.039e-05" ] }, "execution_count": 16, @@ -2466,7 +2487,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "However, in many cases it is more convenient to work with a XArray DataArray. The DataArray can only contain a single dependent variable and can be obtained from the Dataset by indexing using the parameter name." + "However, in many cases it is more convenient to work with a XArray [DataArray](http://xarray.pydata.org/en/stable/data-structures.html?#dataarray). The DataArray can only contain a single dependent variable and can be obtained from the Dataset by indexing using the parameter name." ] }, { @@ -2487,7 +2508,7 @@ "data": { "text/plain": [ "\n", - "array([[-3.724157e-04, 2.674091e-04, 2.168524e-04, ..., 5.451526e-07,\n", + "array([[-5.073949e-04, 7.058781e-04, 9.828259e-05, ..., 5.451526e-07,\n", " 4.808069e-07, 4.233782e-07],\n", " [ 7.680241e-10, 9.298480e-10, 1.123969e-09, ..., 5.951812e-07,\n", " 5.249305e-07, 4.622315e-07],\n", @@ -2516,7 +2537,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -3302,7 +3323,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -3317,16 +3338,16 @@ "xaDataArray.plot(ax=ax[0,0])\n", "xaDataArray.mean(dim='dac_ch1').plot(ax=ax[1,0])\n", "xaDataArray.mean(dim='dac_ch2').plot(ax=ax[0,1])\n", - "xaDataArray[[200]].plot(ax=ax[1,1])\n", + "xaDataArray[200,:].plot(ax=ax[1,1])\n", "fig.tight_layout()" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "Above we demonstrate a few ways to index the data from a DataArray. For instance the DataArray can be directly plotted, the mean extracted or a specific row/column selected." + ] } ], "metadata": { From 863de65011ed1c6280e76315c11bb4ca13a5c4ea Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 6 Feb 2019 13:23:25 +0100 Subject: [PATCH 713/719] Update test docstrings --- .../test_database_creation_and_upgrading.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/qcodes/tests/dataset/test_database_creation_and_upgrading.py b/qcodes/tests/dataset/test_database_creation_and_upgrading.py index ce68d276e17..d2cc5e2b76a 100644 --- a/qcodes/tests/dataset/test_database_creation_and_upgrading.py +++ b/qcodes/tests/dataset/test_database_creation_and_upgrading.py @@ -125,7 +125,8 @@ def test_perform_actual_upgrade_0_to_1(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the " + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=0) as conn: @@ -183,7 +184,8 @@ def test_perform_actual_upgrade_2_to_3_empty(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the " + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: @@ -212,7 +214,8 @@ def test_perform_actual_upgrade_2_to_3_empty_runs(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the " + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: @@ -227,7 +230,8 @@ def test_perform_actual_upgrade_2_to_3_some_runs(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the" + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: @@ -319,7 +323,8 @@ def test_perform_upgrade_v2_v3_to_v4_fixes(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the" + " https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: @@ -449,10 +454,9 @@ def test_perform_upgrade_v2_v3_to_v4_fixes(): assert p5.unit == "unit 5" -def test_perform_upgrade_v3_to_v4_fixes(): +def test_perform_upgrade_v3_to_v4(): """ - Test that a db that was upgraded from v2 to v3 with a buggy - version will be corrected when upgraded to v4. + Test that a db upgrade from v2 to v4 works correctly. """ v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') @@ -461,7 +465,8 @@ def test_perform_upgrade_v3_to_v4_fixes(): if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the " + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: @@ -530,6 +535,7 @@ def test_perform_upgrade_v3_to_v4_fixes(): assert p5.label == "Parameter 5" assert p5.unit == "unit 5" + @pytest.mark.usefixtures("empty_temp_db") def test_update_existing_guids(caplog): @@ -643,7 +649,8 @@ def test_getting_db_version(version): if not os.path.exists(dbname): pytest.skip("No db-file fixtures found. You can generate test db-files" - " using the scripts in the legacy_DB_generation folder") + " using the scripts in the " + "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") (db_v, new_v) = get_db_version_and_newest_available_version(dbname) From 6824df549e753847b15a34dc4ee4496b0cf7b05e Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 6 Feb 2019 13:23:44 +0100 Subject: [PATCH 714/719] Correct docstring --- qcodes/dataset/sqlite_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 6eaca9948c3..8cf48f6c971 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -718,7 +718,7 @@ def perform_db_upgrade_3_to_4(conn: ConnectionPlus) -> None: resulting in the parameter being marked inferred_from for each char in the inferred_from variable and inferred_from was not handled correctly for parameters that were neither dependencies nor dependent on - other parameters. Both have since been fixes so rerun the upgrade. + other parameters. Both have since been fixed so rerun the upgrade. """ no_of_runs_query = "SELECT max(run_id) FROM runs" From 778de4dc1d83e7bd0142ad99f7aa4fadf03b3fec Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 6 Feb 2019 13:26:24 +0100 Subject: [PATCH 715/719] More consistent variable names --- qcodes/dataset/sqlite_base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qcodes/dataset/sqlite_base.py b/qcodes/dataset/sqlite_base.py index 8cf48f6c971..90d2721e8e6 100644 --- a/qcodes/dataset/sqlite_base.py +++ b/qcodes/dataset/sqlite_base.py @@ -606,7 +606,7 @@ def _2to3_get_paramspecs(conn: ConnectionPlus, # depend, then the dependent ParamSpecs and finally the rest for layout_id in list(indeps) + list(deps) + list(the_rest): - (name, label, unit, inferred_from) = layouts[layout_id] + (name, label, unit, inferred_from_str) = layouts[layout_id] # get the data type sql = f'PRAGMA TABLE_INFO("{result_table_name}")' c = transaction(conn, sql) @@ -615,7 +615,7 @@ def _2to3_get_paramspecs(conn: ConnectionPlus, paramtype = row['type'] break - inferred_from_list: List[str] = [] + inferred_from: List[str] = [] depends_on: List[str] = [] # this parameter depends on another parameter @@ -623,14 +623,14 @@ def _2to3_get_paramspecs(conn: ConnectionPlus, setpoints = dependencies[layout_id] depends_on = [paramspecs[idp].name for idp in setpoints] - if inferred_from != '': - inferred_from_list = inferred_from.split(', ') + if inferred_from_str != '': + inferred_from = inferred_from_str.split(', ') paramspec = ParamSpec(name=name, paramtype=paramtype, label=label, unit=unit, depends_on=depends_on, - inferred_from=inferred_from_list) + inferred_from=inferred_from) paramspecs[layout_id] = paramspec return paramspecs From c9f6bbdb50ab39e98f1dba66ccc10ad3c0cff4af Mon Sep 17 00:00:00 2001 From: WilliamHPNielsen Date: Wed, 6 Feb 2019 14:32:32 +0100 Subject: [PATCH 716/719] Fix a few typos --- .../Working-With-Pandas-and-XArray.ipynb | 1321 ++++++++++++++--- 1 file changed, 1074 insertions(+), 247 deletions(-) diff --git a/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb b/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb index f8145fbb8fb..b5fb736da4f 100644 --- a/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb +++ b/docs/examples/DataSet/Working-With-Pandas-and-XArray.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This notebook is demonstrates how Pandas and XArray can be used to work with the QCoDeS Dataset. It is not meant as a general introduction to Pandas and XAarray. We refer to the official documentation for [Pandas](https://pandas.pydata.org/) and [XArray](http://xarray.pydata.org/en/stable/) for this. This notebook requires that both Pandas and XArray is installed." + "This notebook demonstrates how Pandas and XArray can be used to work with the QCoDeS Dataset. It is not meant as a general introduction to Pandas and XArray. We refer to the official documentation for [Pandas](https://pandas.pydata.org/) and [XArray](http://xarray.pydata.org/en/stable/) for this. This notebook requires that both Pandas and XArray are installed." ] }, { @@ -25,7 +25,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "First we borrow an example from the Dataset notebook to have some data to work with. We split the measurement in two so we can try merging it with Pandas." + "First we borrow an example from the measurement notebook to have some data to work with. We split the measurement in two so we can try merging it with Pandas." ] }, { @@ -39,7 +39,7 @@ "text": [ "Logging hadn't been started.\n", "Activating auto-logging. Current session state plus future input saved.\n", - "Filename : C:\\Users\\jenielse\\.qcodes\\logs\\command_history.log\n", + "Filename : C:\\Users\\wihpniel\\.qcodes\\logs\\command_history.log\n", "Mode : append\n", "Output logging : True\n", "Raw input log : False\n", @@ -56,7 +56,7 @@ "import matplotlib.pyplot as plt\n", "\n", "import qcodes as qc\n", - "from qcodes.dataset.experiment_container import new_experiment\n", + "from qcodes.dataset.experiment_container import load_or_create_experiment\n", "from qcodes.dataset.database import initialise_database\n", "from qcodes.tests.instrument_mocks import DummyInstrument\n", "from qcodes.dataset.measurements import Measurement\n", @@ -84,8 +84,10 @@ { "data": { "text/plain": [ - "tutorial_exp#no sample#136@C:\\Users\\jenielse/experiments.db\n", - "-----------------------------------------------------------" + "working_with_pandas#no sample#7@C:\\Users\\wihpniel\\src\\Qcodes\\docs\\examples\\DataSet/db_files/mvmhqlmnfs.db\n", + "---------------------------------------------------------------------------------------------------------\n", + "86-results-1-dac_ch1,dac_ch2,dmm_v1-40200\n", + "87-results-2-dac_ch1,dac_ch2,dmm_v1-40401" ] }, "execution_count": 3, @@ -95,7 +97,8 @@ ], "source": [ "initialise_database()\n", - "new_experiment(name='tutorial_exp', sample_name=\"no sample\")" + "load_or_create_experiment(experiment_name='working_with_pandas',\n", + " sample_name=\"no sample\")" ] }, { @@ -106,7 +109,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 4, @@ -115,14 +118,10 @@ } ], "source": [ - "# For the 2D, we'll need a new batch of parameters, notably one with two \n", - "# other parameters as setpoints. We therefore define a new Measurement\n", - "# with new parameters\n", - "\n", "meas = Measurement()\n", "meas.register_parameter(dac.ch1) # register the first independent parameter\n", "meas.register_parameter(dac.ch2) # register the second independent parameter\n", - "meas.register_parameter(dmm.v1, setpoints=(dac.ch1, dac.ch2)) # now register the dependent oone" + "meas.register_parameter(dmm.v1, setpoints=(dac.ch1, dac.ch2)) # register the dependent one" ] }, { @@ -179,7 +178,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 478\n" + "Starting experimental run with id: 88\n" ] } ], @@ -210,7 +209,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting experimental run with id: 479\n" + "Starting experimental run with id: 89\n" ] } ], @@ -236,7 +235,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "`get_data_as_pandas_dataframe` returns the data as a dict from measured (dependent) parameters to DataFrames. Here we are only interested in the dataframe of a single parameter so we selec that from the dict." + "`get_data_as_pandas_dataframe` returns the data as a dict from measured (dependent) parameters to DataFrames. Here we are only interested in the dataframe of a single parameter, so we select that from the dict." ] }, { @@ -250,13 +249,134 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Lets first inspect the Pandas DataFrame. Note how both dependent variables are used for the index. Pandas refers to this as a [MultiIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html)" + "Lets first inspect the Pandas DataFrame. Note how both dependent variables are used for the index. Pandas refers to this as a [MultiIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html). For visual clarity, we just look at the first N points of the dataset." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, + "outputs": [], + "source": [ + "N = 10" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
dmm_v1
dac_ch1dac_ch2
-1.0-1.00-0.000271
-0.99-0.000081
-0.980.000111
-0.970.000140
-0.96-0.000240
-0.95-0.000176
-0.940.000081
-0.93-0.000004
-0.920.000008
-0.91-0.000002
\n", + "
" + ], + "text/plain": [ + " dmm_v1\n", + "dac_ch1 dac_ch2 \n", + "-1.0 -1.00 -0.000271\n", + " -0.99 -0.000081\n", + " -0.98 0.000111\n", + " -0.97 0.000140\n", + " -0.96 -0.000240\n", + " -0.95 -0.000176\n", + " -0.94 0.000081\n", + " -0.93 -0.000004\n", + " -0.92 0.000008\n", + " -0.91 -0.000002" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1[:N]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also reset the index to return a simpler view where all data points are simply indexed by a running counter. As we shall see below this can be needed in some situations. Note that calling `reset_index` leaves the original dataframe untouched." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, "outputs": [ { "data": { @@ -267,236 +387,943 @@ " vertical-align: middle;\n", " }\n", "\n", - " .dataframe tbody tr th {\n", - " vertical-align: top;\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
dac_ch1dac_ch2dmm_v1
0-1.0-1.00-0.000271
1-1.0-0.99-0.000081
2-1.0-0.980.000111
3-1.0-0.970.000140
4-1.0-0.96-0.000240
5-1.0-0.95-0.000176
6-1.0-0.940.000081
7-1.0-0.93-0.000004
8-1.0-0.920.000008
9-1.0-0.91-0.000002
\n", + "
" + ], + "text/plain": [ + " dac_ch1 dac_ch2 dmm_v1\n", + "0 -1.0 -1.00 -0.000271\n", + "1 -1.0 -0.99 -0.000081\n", + "2 -1.0 -0.98 0.000111\n", + "3 -1.0 -0.97 0.000140\n", + "4 -1.0 -0.96 -0.000240\n", + "5 -1.0 -0.95 -0.000176\n", + "6 -1.0 -0.94 0.000081\n", + "7 -1.0 -0.93 -0.000004\n", + "8 -1.0 -0.92 0.000008\n", + "9 -1.0 -0.91 -0.000002" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1.reset_index()[0:N]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pandas has built-in support for various forms of plotting. This does not, however, support MultiIndex at the moment so we use `reset_index` to make the data available for plotting." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('