From 72b4b425775c94ad54df923b048cf0d36a4b2b7f Mon Sep 17 00:00:00 2001 From: TUD278427 <TUD278427@tudelft.net> Date: Thu, 4 Jun 2020 13:56:45 +0200 Subject: [PATCH] make hardware snapshottable --- core_tools/drivers/harware.py | 256 ++++++++++++++++++---------------- 1 file changed, 137 insertions(+), 119 deletions(-) diff --git a/core_tools/drivers/harware.py b/core_tools/drivers/harware.py index 7d523612..1a5944cc 100644 --- a/core_tools/drivers/harware.py +++ b/core_tools/drivers/harware.py @@ -2,142 +2,160 @@ from dataclasses import dataclass import qcodes as qc import numpy as np import shelve +from typing import Sequence @dataclass class virtual_gate: - name:str - real_gate_names: list - virtual_gate_names: list - virtual_gate_matrix: np.ndarray - - def __init__(self, name, real_gate_names, virtual_gate_names=None): - ''' - generate a virtual gate object. - Args: - real_gate_names (list<str>) : list with the names of real gates - virtual_gate_names (list<str>) : (optional) names of the virtual gates set. If not provided a "v" is inserted before the gate name. - ''' - self.name = name - self.real_gate_names = real_gate_names - self.virtual_gate_matrix = np.eye(len(real_gate_names)).data - if virtual_gate_names != None: - self.virtual_gate_names = virtual_gate_names - else: - self.virtual_gate_names = [] - for name in real_gate_names: - self.virtual_gate_names.append("v" + name) - - if len(self.real_gate_names) != len(self.virtual_gate_names): - raise ValueError("number of real gates and virtual gates is not equal, please fix the input.") - - def __len__(self): - ''' - get number of gate in the object. - ''' - return len(self.real_gate_names) - - def __getstate__(self): - ''' - overwrite state methods so object becomes pickable. - ''' - state = self.__dict__.copy() - state["virtual_gate_matrix"] = np.asarray(self.virtual_gate_matrix) - return state - - def __setstate__(self, new_state): - ''' - overwrite state methods so object becomes pickable. - ''' - new_state["virtual_gate_matrix"] = np.asarray(new_state["virtual_gate_matrix"]).data - self.__dict__.update(new_state) + name:str + real_gate_names: list + virtual_gate_names: list + virtual_gate_matrix: np.ndarray + + def __init__(self, name, real_gate_names, virtual_gate_names=None): + ''' + generate a virtual gate object. + Args: + real_gate_names (list<str>) : list with the names of real gates + virtual_gate_names (list<str>) : (optional) names of the virtual gates set. If not provided a "v" is inserted before the gate name. + ''' + self.name = name + self.real_gate_names = real_gate_names + self.virtual_gate_matrix = np.eye(len(real_gate_names)).data + if virtual_gate_names != None: + self.virtual_gate_names = virtual_gate_names + else: + self.virtual_gate_names = [] + for name in real_gate_names: + self.virtual_gate_names.append("v" + name) + + if len(self.real_gate_names) != len(self.virtual_gate_names): + raise ValueError("number of real gates and virtual gates is not equal, please fix the input.") + + def __len__(self): + ''' + get number of gate in the object. + ''' + return len(self.real_gate_names) + + def __getstate__(self): + ''' + overwrite state methods so object becomes pickable. + ''' + state = self.__dict__.copy() + state["virtual_gate_matrix"] = np.asarray(self.virtual_gate_matrix) + return state + + def __setstate__(self, new_state): + ''' + overwrite state methods so object becomes pickable. + ''' + new_state["virtual_gate_matrix"] = np.asarray(new_state["virtual_gate_matrix"]).data + self.__dict__.update(new_state) class virtual_gates_mgr(list): - def __init__(self, sync_engine, *args): - super(virtual_gates_mgr, self).__init__(*args) + def __init__(self, sync_engine, *args): + super(virtual_gates_mgr, self).__init__(*args) - self.sync_engine = sync_engine + self.sync_engine = sync_engine - def append(self, item): - if not isinstance(item, virtual_gate): - raise ValueError("please provide the virtual gates with the virtual_gate data type. {} detected".format(type(item))) + def append(self, item): + if not isinstance(item, virtual_gate): + raise ValueError("please provide the virtual gates with the virtual_gate data type. {} detected".format(type(item))) - # check for uniqueness of the virtual gate names. - virtual_gates = [] - virtual_gates += item.virtual_gate_names - for i in self: - virtual_gates += i.virtual_gate_names + # check for uniqueness of the virtual gate names. + virtual_gates = [] + virtual_gates += item.virtual_gate_names + for i in self: + virtual_gates += i.virtual_gate_names - if len(np.unique(np.array(virtual_gates))) != len(virtual_gates): - raise ValueError("two duplicate names of virtual gates detected. Please fix this.") + if len(np.unique(np.array(virtual_gates))) != len(virtual_gates): + raise ValueError("two duplicate names of virtual gates detected. Please fix this.") - if item.name in list(self.sync_engine.keys()): - item_in_ram = self.sync_engine[item.name] - if item_in_ram.real_gate_names == item.real_gate_names: - np.asarray(item.virtual_gate_matrix)[:] = np.asarray(item_in_ram.virtual_gate_matrix)[:] + if item.name in list(self.sync_engine.keys()): + item_in_ram = self.sync_engine[item.name] + if item_in_ram.real_gate_names == item.real_gate_names: + np.asarray(item.virtual_gate_matrix)[:] = np.asarray(item_in_ram.virtual_gate_matrix)[:] - self.sync_engine[item.name] = item + self.sync_engine[item.name] = item - return super(virtual_gates_mgr, self).append(item) + return super(virtual_gates_mgr, self).append(item) - def __getitem__(self, row): - if isinstance(row, int): - return super(virtual_gates_mgr, self).__getitem__(row) - if isinstance(row, str): - row = self.index(row) - return super(virtual_gates_mgr, self).__getitem__(row) + def __getitem__(self, row): + if isinstance(row, int): + return super(virtual_gates_mgr, self).__getitem__(row) + if isinstance(row, str): + row = self.index(row) + return super(virtual_gates_mgr, self).__getitem__(row) - raise ValueError("Invalid key (name) {} provided for the virtual_gate object.") + raise ValueError("Invalid key (name) {} provided for the virtual_gate object.") - def index(self, name): - i = 0 - options = [] - for v_gate_item in self: - options.append(v_gate_item.name) - if v_gate_item.name == name: - return i - i += 1 - if len(options) == 0: - raise ValueError("Trying to get find a virtual gate matrix, but no matrix is defined.") + def index(self, name): + i = 0 + options = [] + for v_gate_item in self: + options.append(v_gate_item.name) + if v_gate_item.name == name: + return i + i += 1 + if len(options) == 0: + raise ValueError("Trying to get find a virtual gate matrix, but no matrix is defined.") - raise ValueError("{} is not defined as a virtual gate. The options are, {}".format(name,options)) + raise ValueError("{} is not defined as a virtual gate. The options are, {}".format(name,options)) class harware_parent(qc.Instrument): - """docstring for harware_parent -- init a empy hardware object""" - def __init__(self, sample_name, storage_location): - super(harware_parent, self).__init__(sample_name) - self.storage_location = storage_location - self.sync = shelve.open(sample_name, flag='c', writeback=True) - self.dac_gate_map = dict() - self.boundaries = dict() - # set this one in the GUI. - self._AWG_to_dac_conversion = dict() - if 'AWG2DAC' in list(self.sync.keys()): - self._AWG_to_dac_conversion = self.sync['AWG2DAC'] - self._virtual_gates = virtual_gates_mgr(self.sync) - - @property - def virtual_gates(self): - return self._virtual_gates - - @property - def AWG_to_dac_conversion(self): - return self._AWG_to_dac_conversion - - @AWG_to_dac_conversion.setter - def AWG_to_dac_conversion(self, AWG_to_dac_ratio): - if self._AWG_to_dac_conversion.keys() == AWG_to_dac_ratio.keys(): - AWG_to_dac_ratio = self._AWG_to_dac_conversion - else: - self._AWG_to_dac_conversion = AWG_to_dac_ratio - - def sync_data(self): - for item in self.virtual_gates: - self.sync[item.name] = item - self.sync['AWG2DAC'] = self._AWG_to_dac_conversion - self.sync.sync() + """docstring for harware_parent -- init a empy hardware object""" + def __init__(self, sample_name, storage_location): + super(harware_parent, self).__init__(sample_name) + self.storage_location = storage_location + self.sync = shelve.open(sample_name, flag='c', writeback=True) + self.dac_gate_map = dict() + self.boundaries = dict() + # set this one in the GUI. + self._AWG_to_dac_conversion = dict() + if 'AWG2DAC' in list(self.sync.keys()): + self._AWG_to_dac_conversion = self.sync['AWG2DAC'] + self._virtual_gates = virtual_gates_mgr(self.sync) + + @property + def virtual_gates(self): + return self._virtual_gates + + @property + def AWG_to_dac_conversion(self): + return self._AWG_to_dac_conversion + + @AWG_to_dac_conversion.setter + def AWG_to_dac_conversion(self, AWG_to_dac_ratio): + if self._AWG_to_dac_conversion.keys() == AWG_to_dac_ratio.keys(): + AWG_to_dac_ratio = self._AWG_to_dac_conversion + else: + self._AWG_to_dac_conversion = AWG_to_dac_ratio + + def sync_data(self): + for item in self.virtual_gates: + self.sync[item.name] = item + self.sync['AWG2DAC'] = self._AWG_to_dac_conversion + self.sync.sync() + + def snapshot_base(self, update: bool=False, + params_to_skip_update: Sequence[str]=None): + + vg_snap = {} + for vg in self.virtual_gates: + vg_mat = np.reshape(np.frombuffer(vg.virtual_gate_matrix, dtype=float),np.shape(vg.virtual_gate_matrix)) + vg_meta = {} + vg_meta['real_gate_names'] = vg.real_gate_names + vg_meta['virtual_gate_names'] = vg.virtual_gate_names + vg_meta['virtual_gate_matrix'] = vg_mat + vg_snap[vg.name] = vg_meta + self.snap = {'AWG_to_DAC': self.AWG_to_dac_conversion, + 'dac_gate_map': self.dac_gate_map, + 'virtual_gates': vg_snap + } + return self.snap if __name__ == '__main__': - from V2_software.drivers.virtual_gates.examples.hardware_example import hardware_example - # example. - hw = hardware_example("my_harware_example") - print(hw.virtual_gates) \ No newline at end of file + from V2_software.drivers.virtual_gates.examples.hardware_example import hardware_example + # example. + hw = hardware_example("my_harware_example") + print(hw.virtual_gates) \ No newline at end of file -- GitLab