diff --git a/docs/examples/QDevil/QDAC2/Debugging.ipynb b/docs/examples/QDevil/QDAC2/Debugging.ipynb index a8d6643c4..71d75a9e2 100644 --- a/docs/examples/QDevil/QDAC2/Debugging.ipynb +++ b/docs/examples/QDevil/QDAC2/Debugging.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "221a9199", "metadata": {}, "outputs": [ @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.4) in 0.23s\n" + "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.7) in 0.21s\n" ] } ], @@ -35,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "b936eb6b", "metadata": {}, "outputs": [ @@ -51,7 +51,7 @@ "qdac.start_recording_scpi()\n", "arrangement = qdac.arrange(\n", " # QDAC channels 1, 2, 3, 4 connected to sample\n", - " gates={'plunger2': 2, 'plunger3': 3},\n", + " contacts={'plunger2': 2, 'plunger3': 3},\n", " # DMM external trigger connected to QDAC Output Trigger 4\n", " output_triggers={'dmm': 4})\n", "pp.pprint(qdac.get_recorded_scpi_commands())" @@ -59,15 +59,15 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "7c425791", "metadata": {}, "outputs": [], "source": [ "sweep = arrangement.virtual_sweep2d(\n", - " inner_gate='plunger2',\n", + " inner_contact='plunger2',\n", " inner_voltages=np.linspace(-0.2, 0.6, 5),\n", - " outer_gate='plunger3',\n", + " outer_contact='plunger3',\n", " outer_voltages=np.linspace(-0.7, 0.15, 4),\n", " inner_step_time_s=10e-6,\n", " inner_step_trigger='dmm')" @@ -75,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "0319f497", "metadata": { "scrolled": false diff --git a/docs/examples/QDevil/QDAC2/GateLeakage.ipynb b/docs/examples/QDevil/QDAC2/GateLeakage.ipynb index 1160a2d93..5f81a04ce 100644 --- a/docs/examples/QDevil/QDAC2/GateLeakage.ipynb +++ b/docs/examples/QDevil/QDAC2/GateLeakage.ipynb @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.4) in 0.21s\n" + "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.7) in 0.20s\n" ] } ], @@ -34,13 +34,13 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 2, "id": "30e8b591", "metadata": {}, "outputs": [], "source": [ "arrangement = qdac.arrange(\n", - " gates={'G1': 1, 'G2': 2, 'G3': 3, 'G4': 4, 'G5': 5})\n", + " contacts={'G1': 1, 'G2': 2, 'G3': 3, 'G4': 4, 'G5': 5})\n", "arrangement.set_virtual_voltages({\n", " 'G1': 0.01, 'G2': 0.015, 'G3': 0.013, 'G4': 0.021, 'G5': 0.005})\n", "sleep(3)" @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 3, "id": "be17c0ff", "metadata": {}, "outputs": [], @@ -61,13 +61,13 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 4, "id": "de82ee13", "metadata": {}, "outputs": [], "source": [ "leakage_megaohm = leakage_matrix_Ohm / 1e6\n", - "ticks = np.arange(len(arrangement.gate_names))" + "ticks = np.arange(len(arrangement.contact_names))" ] }, { @@ -93,8 +93,8 @@ "plt.title(f'Gate Leakage ({modulation_mV}mV)')\n", "img = ax.imshow(leakage_megaohm, interpolation='none', vmin=0, vmax=100)\n", "minorticks = np.arange(-0.5, len(ticks), 1)\n", - "ax.set_xticks(ticks, labels=arrangement.gate_names)\n", - "ax.set_yticks(ticks, labels=arrangement.gate_names)\n", + "ax.set_xticks(ticks, labels=arrangement.contact_names)\n", + "ax.set_yticks(ticks, labels=arrangement.contact_names)\n", "ax.set_xticks(minorticks, minor=True)\n", "ax.set_yticks(minorticks, minor=True)\n", "ax.grid(which='minor', color='grey', linewidth=1.5)\n", @@ -102,14 +102,6 @@ "colorbar = fig.colorbar(img)\n", "colorbar.set_label('Resistance (MΩ)')" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f1f68908", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/docs/examples/QDevil/QDAC2/Scan.ipynb b/docs/examples/QDevil/QDAC2/Scan.ipynb index 321872145..0729c2709 100644 --- a/docs/examples/QDevil/QDAC2/Scan.ipynb +++ b/docs/examples/QDevil/QDAC2/Scan.ipynb @@ -18,8 +18,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.4) in 0.21s\n", - "Connected to: RIGOL TECHNOLOGIES DS1104Z (serial:DS1ZA171812151, firmware:00.04.03) in 0.05s\n" + "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.7) in 0.21s\n", + "Connected to: RIGOL TECHNOLOGIES DS1104Z (serial:DS1ZA171812151, firmware:00.04.03) in 0.01s\n" ] } ], @@ -101,7 +101,7 @@ "source": [ "arrangement = qdac.arrange(\n", " # QDAC channels 2 & 3 connected to sample\n", - " gates={'plunger2': 2, 'plunger3': 3},\n", + " contacts={'plunger2': 2, 'plunger3': 3},\n", " # DMM external trigger connected to QDAC Output Trigger 4\n", " output_triggers={'dmm': 4})" ] @@ -115,7 +115,7 @@ "source": [ "# Perform 1D sweep\n", "sweep = arrangement.virtual_sweep(\n", - " gate='plunger2',\n", + " contact='plunger2',\n", " voltages=np.linspace(-0.5, 0.5, 25),\n", " step_time_s=10e-6,\n", " step_trigger='dmm')" @@ -163,9 +163,9 @@ "source": [ "# Perform 2D sweep\n", "sweep = arrangement.virtual_sweep2d(\n", - " inner_gate='plunger2',\n", + " inner_contact='plunger2',\n", " inner_voltages=np.linspace(-0.2, 0.6, 5),\n", - " outer_gate='plunger3',\n", + " outer_contact='plunger3',\n", " outer_voltages=np.linspace(-0.7, 0.15, 4),\n", " inner_step_time_s=10e-6,\n", " inner_step_trigger='dmm')" @@ -213,7 +213,7 @@ "source": [ "# Perform a detuning by sweeping two times between -0.2 to 0.2 and 0.0 to -0.3\n", "sweep = arrangement.virtual_detune(\n", - " gates=('plunger2', 'plunger3'), \n", + " contacts=('plunger2', 'plunger3'), \n", " start_V=(-0.2, 0.0), \n", " end_V=(0.2, -0.3), \n", " steps=5,\n", diff --git a/docs/examples/QDevil/QDAC2/Scan2DDiode.ipynb b/docs/examples/QDevil/QDAC2/Scan2DDiode.ipynb index 4daee419f..3ea08baa0 100644 --- a/docs/examples/QDevil/QDAC2/Scan2DDiode.ipynb +++ b/docs/examples/QDevil/QDAC2/Scan2DDiode.ipynb @@ -71,7 +71,7 @@ "source": [ "arrangement = qdac.arrange(\n", " # QDAC channels 2 & 3 connected to the ends of two back-to-back Ge diodes\n", - " gates={'diodes_left': 2, 'diodes_right': 3},\n", + " contacts={'diodes_left': 2, 'diodes_right': 3},\n", " # Internal trigger for measuring current\n", " internal_triggers={'inner'})\n", "inner_steps = 21\n", @@ -79,9 +79,9 @@ "outer_steps = 21\n", "outer_V = np.linspace(-0.2, 0.5, outer_steps)\n", "sweep = arrangement.virtual_sweep2d(\n", - " inner_gate='diodes_left',\n", + " inner_contact='diodes_left',\n", " inner_voltages=inner_V,\n", - " outer_gate='diodes_right',\n", + " outer_contact='diodes_right',\n", " outer_voltages=outer_V,\n", " inner_step_time_s=20e-3,\n", " inner_step_trigger='inner')\n", diff --git a/docs/examples/QDevil/QDAC2/VirtualGates.ipynb b/docs/examples/QDevil/QDAC2/VirtualGates.ipynb index a03db2015..81c2c884c 100644 --- a/docs/examples/QDevil/QDAC2/VirtualGates.ipynb +++ b/docs/examples/QDevil/QDAC2/VirtualGates.ipynb @@ -18,7 +18,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.4) in 0.21s\n", + "Connected to: QDevil QDAC-II (serial:3, firmware:10-1.7) in 0.21s\n", "Connected to: RIGOL TECHNOLOGIES DS1104Z (serial:DS1ZA171812151, firmware:00.04.03) in 0.01s\n" ] } @@ -107,7 +107,7 @@ "source": [ "arrangement = qdac.arrange(\n", " # QDAC channels 1, 2, 3, 4 connected to sample\n", - " gates={'sensor1': 1, 'plunger2': 2, 'plunger3': 3, 'plunger4': 4},\n", + " contacts={'sensor1': 1, 'plunger2': 2, 'plunger3': 3, 'plunger4': 4},\n", " # DMM external trigger connected to QDAC Output Trigger 4\n", " output_triggers={'dmm': 4})" ] @@ -122,9 +122,9 @@ "# Start without correction\n", "arrangement.set_virtual_voltage('plunger4', 0.1)\n", "sweep = arrangement.virtual_sweep2d(\n", - " inner_gate='plunger2',\n", + " inner_contact='plunger2',\n", " inner_voltages=np.linspace(-0.2, 0.6, 5),\n", - " outer_gate='plunger3',\n", + " outer_contact='plunger3',\n", " outer_voltages=np.linspace(-0.7, 0.15, 4),\n", " inner_step_time_s=10e-6,\n", " inner_step_trigger='dmm')" @@ -205,9 +205,9 @@ "arrangement.initiate_correction('plunger2', [-0.2, 0.98, 0.3, 0.06])\n", "arrangement.initiate_correction('plunger3', [0.01, 0.41, 1.0, 0.15])\n", "sweep = arrangement.virtual_sweep2d(\n", - " inner_gate='plunger2',\n", + " inner_contact='plunger2',\n", " inner_voltages=np.linspace(-0.2, 0.6, 5),\n", - " outer_gate='plunger3',\n", + " outer_contact='plunger3',\n", " outer_voltages=np.linspace(-0.7, 0.15, 4),\n", " inner_step_time_s=10e-6,\n", " inner_step_trigger='dmm')" @@ -287,7 +287,7 @@ "source": [ "# Perform a detuning by sweeping two times between -0.4 to 0.2 and 0.0 to -0.3\n", "sweep = arrangement.virtual_detune(\n", - " gates=('plunger2', 'plunger3'), \n", + " contacts=('plunger2', 'plunger3'), \n", " start_V=(-0.4, 0.0), \n", " end_V=(0.2, -0.3), \n", " steps=5,\n", @@ -330,7 +330,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "b64f2646", "metadata": {}, "outputs": [ diff --git a/qcodes_contrib_drivers/drivers/QDevil/QDAC2.py b/qcodes_contrib_drivers/drivers/QDevil/QDAC2.py index db96a1e31..ac410cbe4 100644 --- a/qcodes_contrib_drivers/drivers/QDevil/QDAC2.py +++ b/qcodes_contrib_drivers/drivers/QDevil/QDAC2.py @@ -9,7 +9,7 @@ from typing import Any, NewType, Sequence, List, Dict, Tuple, Optional from packaging.version import parse -# Version 0.21.0 +# Version 1.0.0 # # Guiding principles for this driver for QDevil QDAC-II # ----------------------------------------------------- @@ -80,7 +80,7 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): self._parent.free_trigger(self) - # Propagate exceptions + # Propacontact exceptions return False @property @@ -187,7 +187,7 @@ def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): - # Propagate exceptions + # Propacontact exceptions return False def allocate_trigger(self) -> QDac2Trigger_Context: @@ -1579,16 +1579,16 @@ def __exit__(self, exc_type, exc_val, exc_tb): # Let Arrangement take care of freeing triggers return False - def actual_values_V(self, gate: str) -> np.ndarray: - """The corrected values that would actually be sent to the gate + def actual_values_V(self, contact: str) -> np.ndarray: + """The corrected values that would actually be sent to the contact Args: - gate (str): Name of gate + contact (str): Name of contact Returns: np.ndarray: Corrected voltages """ - index = self._arrangement._gate_index(gate) + index = self._arrangement._contact_index(contact) return self._sweep[:, index] def start(self) -> None: @@ -1622,34 +1622,34 @@ def _route_inner_trigger(self) -> None: channel.write_channel(f'sour{"{0}"}:dc:mark:sst ' f'{_trigger_context_to_value(trigger)}') - def _get_channel(self, gate_index: int) -> 'QDac2Channel': - channel_number = self._arrangement._channels[gate_index] + def _get_channel(self, contact_index: int) -> 'QDac2Channel': + channel_number = self._arrangement._channels[contact_index] qdac = self._arrangement._qdac return qdac.channel(channel_number) def _send_lists_to_qdac(self) -> None: - for gate_index in range(self._arrangement.shape): - self._send_list_to_qdac(gate_index, self._sweep[:, gate_index]) + for contact_index in range(self._arrangement.shape): + self._send_list_to_qdac(contact_index, self._sweep[:, contact_index]) - def _send_list_to_qdac(self, gate_index, voltages): - channel = self._get_channel(gate_index) + def _send_list_to_qdac(self, contact_index, voltages): + channel = self._get_channel(contact_index) dc_list = channel.dc_list(voltages=voltages, dwell_s=self._step_time_s, repetitions=self._repetitions) trigger = self._arrangement.get_trigger_by_name(self._start_trigger_name) dc_list.start_on(trigger) def _make_ready_to_start(self): # Bug circumvention - for gate_index in range(self._arrangement.shape): - channel = self._get_channel(gate_index) + for contact_index in range(self._arrangement.shape): + channel = self._get_channel(contact_index) channel.write_channel('sour{0}:dc:init') class Arrangement_Context: - def __init__(self, qdac: 'QDac2', gates: Dict[str, int], + def __init__(self, qdac: 'QDac2', contacts: Dict[str, int], output_triggers: Optional[Dict[str, int]], internal_triggers: Optional[Sequence[str]]): self._qdac = qdac - self._fix_gate_order(gates) + self._fix_contact_order(contacts) self._allocate_triggers(internal_triggers, output_triggers) self._correction = np.identity(self.shape) @@ -1664,9 +1664,9 @@ def __exit__(self, exc_type, exc_val, exc_tb): def shape(self) -> int: """ Returns: - int: Number of gates in the arrangement + int: Number of contacts in the arrangement """ - return len(self._gates) + return len(self._contacts) @property def correction_matrix(self) -> np.ndarray: @@ -1677,8 +1677,8 @@ def correction_matrix(self) -> np.ndarray: return self._correction @property - def gate_names(self) -> Sequence[str]: - return self._gate_names + def contact_names(self) -> Sequence[str]: + return self._contact_names def _allocate_internal_triggers(self, internal_triggers: Optional[Sequence[str]] @@ -1688,46 +1688,46 @@ def _allocate_internal_triggers(self, for name in internal_triggers: self._internal_triggers[name] = self._qdac.allocate_trigger() - def initiate_correction(self, gate: str, factors: Sequence[float]) -> None: - """Override how much a particular gate influences the other gates + def initiate_correction(self, contact: str, factors: Sequence[float]) -> None: + """Override how much a particular contact influences the other contacts Args: - gate (str): Name of gate + contact (str): Name of contact factors (Sequence[float]): factors between -1.0 and 1.0 """ - index = self._gate_index(gate) + index = self._contact_index(contact) self._correction[index] = factors - def set_virtual_voltage(self, gate: str, voltage: float) -> None: - """Set virtual voltage on specific gate + def set_virtual_voltage(self, contact: str, voltage: float) -> None: + """Set virtual voltage on specific contact - The actual voltage that the gate will receive depends on the + The actual voltage that the contact will receive depends on the correction matrix. Args: - gate (str): Name of gate + contact (str): Name of contact voltage (float): Voltage corresponding to no correction """ try: - index = self._gate_index(gate) + index = self._contact_index(contact) except KeyError: - raise ValueError(f'No gate named "{gate}"') + raise ValueError(f'No contact named "{contact}"') self._effectuate_virtual_voltage(index, voltage) - def set_virtual_voltages(self, gates_to_voltages: Dict[str, float]) -> None: - """Set virtual voltages on specific gates in one go + def set_virtual_voltages(self, contacts_to_voltages: Dict[str, float]) -> None: + """Set virtual voltages on specific contacts in one go - The actual voltage that each gate will receive depends on the + The actual voltage that each contact will receive depends on the correction matrix. Args: - gate_to_voltages (Dict[str,float]): gate to voltage map + contact_to_voltages (Dict[str,float]): contact to voltage map """ - for gate, voltage in gates_to_voltages.items(): + for contact, voltage in contacts_to_voltages.items(): try: - index = self._gate_index(gate) + index = self._contact_index(contact) except KeyError: - raise ValueError(f'No gate named "{gate}"') + raise ValueError(f'No contact named "{contact}"') self._virtual_voltages[index] = voltage self._effectuate_virtual_voltages() @@ -1740,32 +1740,32 @@ def _effectuate_virtual_voltages(self) -> None: actual_V = self.actual_voltages()[index] self._qdac.channel(channel_number).dc_constant_V(actual_V) - def add_correction(self, gate: str, factors: Sequence[float]) -> None: - """Update how much a particular gate influences the other gates + def add_correction(self, contact: str, factors: Sequence[float]) -> None: + """Update how much a particular contact influences the other contacts - This is mostly useful in arrangements where each gate has significant - effect only on nearby gates, and thus can be added incrementally. + This is mostly useful in arrangements where each contact has significant + effect only on nearby contacts, and thus can be added incrementally. The factors are extended by the identity matrix and multiplied to the correction matrix. Args: - gate (str): Name of gate + contact (str): Name of contact factors (Sequence[float]): factors usually between -1.0 and 1.0 """ - index = self._gate_index(gate) + index = self._contact_index(contact) multiplier = np.identity(self.shape) multiplier[index] = factors self._correction = np.matmul(multiplier, self._correction) - def _fix_gate_order(self, gates: Dict[str, int]) -> None: - self._gate_names = [] - self._gates = {} + def _fix_contact_order(self, contacts: Dict[str, int]) -> None: + self._contact_names = [] + self._contacts = {} self._channels = [] index = 0 - for gate, channel in gates.items(): - self._gate_names.append(gate) - self._gates[gate] = index + for contact, channel in contacts.items(): + self._contact_names.append(contact) + self._contacts[contact] = index index += 1 self._channels.append(channel) self._virtual_voltages = np.zeros(self.shape) @@ -1774,21 +1774,21 @@ def _fix_gate_order(self, gates: Dict[str, int]) -> None: def channel_numbers(self) -> Sequence[int]: return self._channels - def virtual_voltage(self, gate: str) -> float: + def virtual_voltage(self, contact: str) -> float: """ Args: - gate (str): Name of gate + contact (str): Name of contact Returns: - float: Virtual voltage on the gate + float: Virtual voltage on the contact """ - index = self._gate_index(gate) + index = self._contact_index(contact) return self._virtual_voltages[index] def actual_voltages(self) -> Sequence[float]: """ Returns: - Sequence[float]: Corrected voltages for all gates + Sequence[float]: Corrected voltages for all contacts """ vs = np.matmul(self._correction, self._virtual_voltages) if self._qdac._round_off: @@ -1810,7 +1810,7 @@ def get_trigger_by_name(self, name: str) -> QDac2Trigger_Context: raise def currents_A(self, nplc: int = 1) -> Sequence[float]: - """Measure currents on all gates + """Measure currents on all contacts Args: nplc (int): Number of powerline cycles to average over @@ -1828,17 +1828,17 @@ def currents_A(self, nplc: int = 1) -> Sequence[float]: currents = self._qdac.ask(f'read? {channels_suffix}') return comma_sequence_to_list_of_floats(currents) - def virtual_sweep(self, gate: str, voltages: Sequence[float], + def virtual_sweep(self, contact: str, voltages: Sequence[float], start_sweep_trigger: Optional[str] = None, step_time_s: float = 1e-5, step_trigger: Optional[str] = None, repetitions: int = 1) -> Virtual_Sweep_Context: - """Sweep a gate to create a 1D sweep + """Sweep a contact to create a 1D sweep Args: - gate (str): Name of sweeping gate + contact (str): Name of sweeping contact voltages (Sequence[float]): Virtual sweep voltages - outer_gate (str): Name of slow-changing (outer) gate + outer_contact (str): Name of slow-changing (outer) contact start_sweep_trigger (None, optional): Trigger that starts sweep step_time_s (float, optional): Delay between voltage changes step_trigger (None, optional): Trigger that marks each step @@ -1847,14 +1847,14 @@ def virtual_sweep(self, gate: str, voltages: Sequence[float], Returns: Virtual_Sweep_Context: context manager """ - sweep = self._calculate_1d_values(gate, voltages) + sweep = self._calculate_1d_values(contact, voltages) return Virtual_Sweep_Context(self, sweep, start_sweep_trigger, step_time_s, step_trigger, repetitions) - def _calculate_1d_values(self, gate: str, voltages: Sequence[float] + def _calculate_1d_values(self, contact: str, voltages: Sequence[float] ) -> np.ndarray: - original_voltage = self.virtual_voltage(gate) - index = self._gate_index(gate) + original_voltage = self.virtual_voltage(contact) + index = self._contact_index(contact) sweep = [] for v in voltages: self._virtual_voltages[index] = v @@ -1863,19 +1863,19 @@ def _calculate_1d_values(self, gate: str, voltages: Sequence[float] return np.array(sweep) - def virtual_sweep2d(self, inner_gate: str, inner_voltages: Sequence[float], - outer_gate: str, outer_voltages: Sequence[float], + def virtual_sweep2d(self, inner_contact: str, inner_voltages: Sequence[float], + outer_contact: str, outer_voltages: Sequence[float], start_sweep_trigger: Optional[str] = None, inner_step_time_s: float = 1e-5, inner_step_trigger: Optional[str] = None, repetitions: int = 1) -> Virtual_Sweep_Context: - """Sweep two gates to create a 2D sweep + """Sweep two contacts to create a 2D sweep Args: - inner_gate (str): Name of fast-changing (inner) gate - inner_voltages (Sequence[float]): Inner gate virtual voltages - outer_gate (str): Name of slow-changing (outer) gate - outer_voltages (Sequence[float]): Outer gate virtual voltages + inner_contact (str): Name of fast-changing (inner) contact + inner_voltages (Sequence[float]): Inner contact virtual voltages + outer_contact (str): Name of slow-changing (outer) contact + outer_voltages (Sequence[float]): Outer contact virtual voltages start_sweep_trigger (None, optional): Trigger that starts sweep inner_step_time_s (float, optional): Delay between voltage changes inner_step_trigger (None, optional): Trigger that marks each step @@ -1884,19 +1884,19 @@ def virtual_sweep2d(self, inner_gate: str, inner_voltages: Sequence[float], Returns: Virtual_Sweep_Context: context manager """ - sweep = self._calculate_2d_values(inner_gate, inner_voltages, - outer_gate, outer_voltages) + sweep = self._calculate_2d_values(inner_contact, inner_voltages, + outer_contact, outer_voltages) return Virtual_Sweep_Context(self, sweep, start_sweep_trigger, inner_step_time_s, inner_step_trigger, repetitions) - def _calculate_2d_values(self, inner_gate: str, + def _calculate_2d_values(self, inner_contact: str, inner_voltages: Sequence[float], - outer_gate: str, + outer_contact: str, outer_voltages: Sequence[float]) -> np.ndarray: - original_fast_voltage = self.virtual_voltage(inner_gate) - original_slow_voltage = self.virtual_voltage(outer_gate) - outer_index = self._gate_index(outer_gate) - inner_index = self._gate_index(inner_gate) + original_fast_voltage = self.virtual_voltage(inner_contact) + original_slow_voltage = self.virtual_voltage(outer_contact) + outer_index = self._contact_index(outer_contact) + inner_index = self._contact_index(inner_contact) sweep = [] for slow_V in outer_voltages: self._virtual_voltages[outer_index] = slow_V @@ -1907,16 +1907,16 @@ def _calculate_2d_values(self, inner_gate: str, self._virtual_voltages[outer_index] = original_slow_voltage return np.array(sweep) - def virtual_detune(self, gates: Sequence[str], start_V: Sequence[float], + def virtual_detune(self, contacts: Sequence[str], start_V: Sequence[float], end_V: Sequence[float], steps: int, start_trigger: Optional[str] = None, step_time_s: float = 1e-5, step_trigger: Optional[str] = None, repetitions: int = 1) -> Virtual_Sweep_Context: - """Sweep any number of gates from one set of values to another set of values + """Sweep any number of contacts from one set of values to another set of values Args: - gates (Sequence[str]): Gates involved in sweep + contacts (Sequence[str]): contacts involved in sweep start_V (Sequence[float]): First-extreme values end_V (Sequence[float]): Second-extreme values steps (int): Number of steps between extremes @@ -1925,25 +1925,25 @@ def virtual_detune(self, gates: Sequence[str], start_V: Sequence[float], step_trigger (None, optional): Trigger that marks each step repetitions (int, Optional): Number of back-and-forth sweeps, or -1 for infinite """ - self._check_same_lengths(gates, start_V, end_V) - sweep = self._calculate_detune_values(gates, start_V, end_V, steps) + self._check_same_lengths(contacts, start_V, end_V) + sweep = self._calculate_detune_values(contacts, start_V, end_V, steps) return Virtual_Sweep_Context(self, sweep, start_trigger, step_time_s, step_trigger, repetitions) @staticmethod - def _check_same_lengths(gates, start_V, end_V) -> None: - n_gates = len(gates) - if n_gates != len(start_V): - raise ValueError(f'There must be exactly one voltage per gate: {start_V}') - if n_gates != len(end_V): - raise ValueError(f'There must be exactly one voltage per gate: {end_V}') - - def _calculate_detune_values(self, gates: Sequence[str], start_V: Sequence[float], + def _check_same_lengths(contacts, start_V, end_V) -> None: + n_contacts = len(contacts) + if n_contacts != len(start_V): + raise ValueError(f'There must be exactly one voltage per contact: {start_V}') + if n_contacts != len(end_V): + raise ValueError(f'There must be exactly one voltage per contact: {end_V}') + + def _calculate_detune_values(self, contacts: Sequence[str], start_V: Sequence[float], end_V: Sequence[float], steps: int): - original_voltages = [self.virtual_voltage(gate) for gate in gates] - indices = [self._gate_index(gate) for gate in gates] + original_voltages = [self.virtual_voltage(contact) for contact in contacts] + indices = [self._contact_index(contact) for contact in contacts] sweep = [] - forward_V = [forward_and_back(start_V[i], end_V[i], steps) for i in range(len(gates))] + forward_V = [forward_and_back(start_V[i], end_V[i], steps) for i in range(len(contacts))] for voltages in zip(*forward_V): for index, voltage in zip(indices, voltages): self._virtual_voltages[index] = voltage @@ -1953,18 +1953,18 @@ def _calculate_detune_values(self, gates: Sequence[str], start_V: Sequence[float return np.array(sweep) def leakage(self, modulation_V: float, nplc: int = 2) -> np.ndarray: - """Run a simple leakage test between the gates + """Run a simple leakage test between the contacts - Each gate is changed in turn and the resulting change in current from + Each contact is changed in turn and the resulting change in current from steady-state is recorded. The resulting resistance matrix is calculated as modulation_voltage divided by current_change. Args: - modulation_V (float): Virtual voltage added to each gate + modulation_V (float): Virtual voltage added to each contact nplc (int, Optional): Powerline cycles to wait for each measurement Returns: - ndarray: gate-to-gate resistance in Ohms + ndarray: contact-to-contact resistance in Ohms """ steady_state_A = self.currents_A(nplc) currents_matrix = [] @@ -1977,8 +1977,8 @@ def leakage(self, modulation_V: float, nplc: int = 2) -> np.ndarray: with np.errstate(divide='ignore'): return np.abs(modulation_V / diff_matrix(steady_state_A, currents_matrix)) - def _gate_index(self, gate: str) -> int: - return self._gates[gate] + def _contact_index(self, contact: str) -> int: + return self._contacts[contact] def _allocate_triggers(self, internal_triggers: Optional[Sequence[str]], output_triggers: Optional[Dict[str, int]] @@ -2195,33 +2195,33 @@ def mac(self) -> str: return f'{mac[1:3]}-{mac[3:5]}-{mac[5:7]}-{mac[7:9]}-{mac[9:11]}' \ f'-{mac[11:13]}' - def arrange(self, gates: Dict[str, int], + def arrange(self, contacts: Dict[str, int], output_triggers: Optional[Dict[str, int]] = None, internal_triggers: Optional[Sequence[str]] = None ) -> Arrangement_Context: - """An arrangement of gates and triggers for virtual 2D sweeps + """An arrangement of contacts and triggers for virtual 2D sweeps - Each gate corresponds to a particular output channel and each trigger + Each contact corresponds to a particular output channel and each trigger corresponds to a particular external or internal trigger. After - initialisation of the arrangement, gates and triggers can only be + initialisation of the arrangement, contacts and triggers can only be referred to by name. - The voltages that will appear on each gate depends not only on the + The voltages that will appear on each contact depends not only on the specified virtual voltage, but also on a correction matrix. - Initially, the gates are assumed to not influence each other, which + Initially, the contacts are assumed to not influence each other, which means that the correction matrix is the identity matrix, ie. the row for - each gate has a value of [0, ..., 0, 1, 0, ..., 0]. + each contact has a value of [0, ..., 0, 1, 0, ..., 0]. Args: - gates (Gates): Name/channel pairs + contacts (Dict[str, int]): Name/channel pairs output_triggers (Optional[Sequence[Tuple[str,int]]], optional): Name/number pairs of output triggers internal_triggers (Optional[Sequence[str]], optional): List of names of internal triggers to allocate Returns: Arrangement_Context: Description """ - return Arrangement_Context(self, gates, output_triggers, + return Arrangement_Context(self, contacts, output_triggers, internal_triggers) # ----------------------------------------------------------------------- diff --git a/qcodes_contrib_drivers/tests/QDevil/test_sim_qdac2_virtual_gates.py b/qcodes_contrib_drivers/tests/QDevil/test_sim_qdac2_virtual_gates.py index b280cde15..83050fbda 100644 --- a/qcodes_contrib_drivers/tests/QDevil/test_sim_qdac2_virtual_gates.py +++ b/qcodes_contrib_drivers/tests/QDevil/test_sim_qdac2_virtual_gates.py @@ -6,31 +6,31 @@ def test_arrangement_default_correction(qdac): # noqa # ----------------------------------------------------------------------- - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) # ----------------------------------------------------------------------- assert np.array_equal(arrangement.correction_matrix, np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])) -def test_arrangement_gate_names(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) +def test_arrangement_contact_names(qdac): # noqa + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) # ----------------------------------------------------------------------- - gates = arrangement.gate_names + contacts = arrangement.contact_names # ----------------------------------------------------------------------- - assert gates == ['plunger1', 'plunger2', 'plunger3'] + assert contacts == ['plunger1', 'plunger2', 'plunger3'] -def test_arrangement_set_virtual_voltage_non_exiting_gate(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger': 1}) +def test_arrangement_set_virtual_voltage_non_exiting_contact(qdac): # noqa + arrangement = qdac.arrange(contacts={'plunger': 1}) # ----------------------------------------------------------------------- with pytest.raises(ValueError) as error: arrangement.set_virtual_voltage('sensor', 1.0) # ----------------------------------------------------------------------- - assert 'No gate named "sensor"' in repr(error) + assert 'No contact named "sensor"' in repr(error) def test_arrangement_set_virtual_voltage_effectuated_immediately(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) qdac.start_recording_scpi() # ----------------------------------------------------------------------- arrangement.set_virtual_voltage('plunger2', 0.5) @@ -47,11 +47,11 @@ def test_arrangement_set_virtual_voltage_effectuated_immediately(qdac): # noqa def test_arrangement_default_actuals_1d(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2}) arrangement.set_virtual_voltage('plunger2', 1.0) # ----------------------------------------------------------------------- sweep = arrangement.virtual_sweep( - gate='plunger1', + contact='plunger1', voltages=np.linspace(-0.1, 0.1, 5), step_time_s=2e-5) # ----------------------------------------------------------------------- @@ -62,12 +62,12 @@ def test_arrangement_default_actuals_1d(qdac): # noqa def test_arrangement_default_actuals_2d(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) # ----------------------------------------------------------------------- sweep = arrangement.virtual_sweep2d( - inner_gate='plunger2', + inner_contact='plunger2', inner_voltages=np.linspace(-0.2, 0.6, 5), - outer_gate='plunger3', + outer_contact='plunger3', outer_voltages=np.linspace(-0.7, 0.15, 5), inner_step_time_s=2e-6) # ----------------------------------------------------------------------- @@ -79,11 +79,11 @@ def test_arrangement_default_actuals_2d(qdac): # noqa def test_arrangement_sweep(qdac): # noqa qdac.free_all_triggers() - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2, 'plunger3': 3}) sweep = arrangement.virtual_sweep2d( - inner_gate='plunger2', + inner_contact='plunger2', inner_voltages=np.linspace(-0.2, 0.6, 5), - outer_gate='plunger3', + outer_contact='plunger3', outer_voltages=np.linspace(-0.7, 0.15, 5), inner_step_time_s=2e-6) qdac.start_recording_scpi() @@ -142,7 +142,7 @@ def test_arrangement_sweep(qdac): # noqa def test_arrangement_context_releases_trigger(qdac): # noqa before = len(qdac._internal_triggers) # ----------------------------------------------------------------------- - with qdac.arrange(gates={}, output_triggers={'dmm': 4}): + with qdac.arrange(contacts={}, output_triggers={'dmm': 4}): pass # ----------------------------------------------------------------------- after = len(qdac._internal_triggers) @@ -152,11 +152,11 @@ def test_arrangement_context_releases_trigger(qdac): # noqa def test_sweep_context_releases_trigger(qdac): # noqa before = len(qdac._internal_triggers) # ----------------------------------------------------------------------- - with qdac.arrange(gates={'plunger1': 1, 'plunger2': 2}) as arrangement: + with qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2}) as arrangement: arrangement.virtual_sweep2d( - inner_gate='plunger1', + inner_contact='plunger1', inner_voltages=np.linspace(-0.2, 0.6, 5), - outer_gate='plunger2', + outer_contact='plunger2', outer_voltages=np.linspace(-0.7, 0.15, 5), inner_step_time_s=1e-6) # ----------------------------------------------------------------------- @@ -165,7 +165,7 @@ def test_sweep_context_releases_trigger(qdac): # noqa def test_arrangement_set_virtual_voltage_affects_whole_arrangement(qdac): # noqa - arrangement = qdac.arrange(gates={'gate1': 1, 'gate2': 2, 'gate3': 3}) + arrangement = qdac.arrange(contacts={'gate1': 1, 'gate2': 2, 'gate3': 3}) arrangement.initiate_correction('gate1', [1.0, 0.5, -0.5]) arrangement.initiate_correction('gate2', [-0.5, 1.0, 0.5]) arrangement.initiate_correction('gate3', [0.0, 0.0, 1.0]) @@ -177,7 +177,6 @@ def test_arrangement_set_virtual_voltage_affects_whole_arrangement(qdac): # noq arrangement.set_virtual_voltage('gate2', 4) # ----------------------------------------------------------------------- commands = qdac.get_recorded_scpi_commands() - print(commands) assert commands == [ 'sour1:volt:mode fix', 'sour1:volt 1.5', @@ -189,7 +188,7 @@ def test_arrangement_set_virtual_voltage_affects_whole_arrangement(qdac): # noq def test_arrangement_set_virtual_voltages_affects_at_once(qdac): # noqa - arrangement = qdac.arrange(gates={'gate1': 1, 'gate2': 2}) + arrangement = qdac.arrange(contacts={'gate1': 1, 'gate2': 2}) arrangement.initiate_correction('gate1', [1.0, 0.12]) arrangement.initiate_correction('gate2', [-0.12, 0.98]) # ----------------------------------------------------------------------- @@ -208,7 +207,7 @@ def test_stability_diagram_external(qdac): # noqa qdac.free_all_triggers() arrangement = qdac.arrange( # QDAC channels 3, 6, 7, 8 connected to sample - gates={'sensor1': 3, 'plunger2': 6, 'plunger3': 7, 'plunger4': 8}, + contacts={'sensor1': 3, 'plunger2': 6, 'plunger3': 7, 'plunger4': 8}, # DMM external trigger connected to QDAC Output Trigger 4 output_triggers={'dmm': 4}) # After tuning first DQD @@ -228,9 +227,9 @@ def test_stability_diagram_external(qdac): # noqa ]), atol=1e-2) # ----------------------------------------------------------------------- sweep = arrangement.virtual_sweep2d( - inner_gate='plunger4', + inner_contact='plunger4', inner_voltages=np.linspace(-0.2, 0.6, 5), - outer_gate='plunger3', + outer_contact='plunger3', outer_voltages=np.linspace(-0.7, 0.15, 5), inner_step_time_s=1e-6, inner_step_trigger='dmm') @@ -356,16 +355,16 @@ def test_stability_diagram_external(qdac): # noqa def test_arrangement_detune_wrong_number_of_voltages(qdac): # noqa - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2}) # ----------------------------------------------------------------------- with pytest.raises(ValueError) as error: arrangement.virtual_detune( - gates=('plunger1', 'plunger2'), + contacts=('plunger1', 'plunger2'), start_V=(-0.3, 0.6), end_V=(0.3,), steps=2) # ----------------------------------------------------------------------- - assert 'There must be exactly one voltage per gate' in repr(error) + assert 'There must be exactly one voltage per contact' in repr(error) def test_forward_and_back(): @@ -375,9 +374,9 @@ def test_forward_and_back(): def test_arrangement_detune(qdac): # noqa qdac.free_all_triggers() - arrangement = qdac.arrange(gates={'plunger1': 1, 'plunger2': 2}) + arrangement = qdac.arrange(contacts={'plunger1': 1, 'plunger2': 2}) detune = arrangement.virtual_detune( - gates=('plunger1', 'plunger2'), + contacts=('plunger1', 'plunger2'), start_V=(-0.3, 0.6), end_V=(0.3, -0.1), steps=5,