Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QDAC2: Clean up triggers and markers on context exit #251

Merged
merged 3 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion qcodes_contrib_drivers/drivers/QDevil/QDAC2.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from packaging.version import Version, parse
import abc

# Version 1.3.0
# Version 1.4.0
#
# Guiding principles for this driver for QDevil QDAC-II
# -----------------------------------------------------
Expand Down Expand Up @@ -230,6 +230,30 @@ def __init__(self, channel: 'QDac2Channel'):
self._marker_step_start: Optional[QDac2Trigger_Context] = None
self._marker_step_end: Optional[QDac2Trigger_Context] = None

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.abort()
if self._trigger:
self._channel._parent.free_trigger(self._trigger)
if self._marker_start:
self._channel._parent.free_trigger(self._marker_start)
self._write_channel(f'sour{"{0}"}:dc:mark:star 0')
if self._marker_end:
self._channel._parent.free_trigger(self._marker_end)
self._write_channel(f'sour{"{0}"}:dc:mark:end 0')
if self._marker_step_start:
self._channel._parent.free_trigger(self._marker_step_start)
self._write_channel(f'sour{"{0}"}:dc:mark:sst 0')
if self._marker_step_end:
self._channel._parent.free_trigger(self._marker_step_end)
self._write_channel(f'sour{"{0}"}:dc:mark:send 0')
# Always disable any triggering
self._write_channel(f'sour{"{0}"}:dc:trig:sour imm')
# Propagate exceptions
return False

def start_on(self, trigger: QDac2Trigger_Context) -> None:
"""Attach internal trigger to DC generator

Expand Down Expand Up @@ -500,6 +524,27 @@ def __init__(self, channel: 'QDac2Channel'):
self._marker_period_start: Optional[QDac2Trigger_Context] = None
self._marker_period_end: Optional[QDac2Trigger_Context] = None

def __enter__(self):
return self

def _cleanup(self, wave_kind: str) -> None:
if self._trigger:
self._channel._parent.free_trigger(self._trigger)
if self._marker_start:
self._channel._parent.free_trigger(self._marker_start)
self._write_channel(f'sour{"{0}"}:{wave_kind}:mark:star 0')
if self._marker_end:
self._channel._parent.free_trigger(self._marker_end)
self._write_channel(f'sour{"{0}"}:{wave_kind}:mark:end 0')
if self._marker_period_start:
self._channel._parent.free_trigger(self._marker_period_start)
self._write_channel(f'sour{"{0}"}:{wave_kind}:mark:pstart 0')
if self._marker_period_end:
self._channel._parent.free_trigger(self._marker_period_end)
self._write_channel(f'sour{"{0}"}:{wave_kind}:mark:pend 0')
# Always disable any triggering
self._write_channel(f'sour{"{0}"}:{wave_kind}:trig:sour imm')

def _start(self, wave_kind: str, description: str) -> None:
if self._trigger:
self._make_ready_to_start(wave_kind)
Expand Down Expand Up @@ -582,6 +627,12 @@ def __init__(self, channel: 'QDac2Channel', frequency_Hz: Optional[float],
self._write_channel(f'sour{"{0}"}:squ:coun {repetitions}')
self._set_triggering()

def __exit__(self, exc_type, exc_val, exc_tb):
self.abort()
super()._cleanup('squ')
# Propagate exceptions
return False

def start(self) -> None:
"""Start the square wave generator
"""
Expand Down Expand Up @@ -699,6 +750,12 @@ def __init__(self, channel: 'QDac2Channel', frequency_Hz: Optional[float],
self._write_channel(f'sour{"{0}"}:sine:coun {repetitions}')
self._set_triggering()

def __exit__(self, exc_type, exc_val, exc_tb):
self.abort()
super()._cleanup('sine')
# Propagate exceptions
return False

def start(self) -> None:
"""Start the sine wave generator
"""
Expand Down Expand Up @@ -809,6 +866,12 @@ def __init__(self, channel: 'QDac2Channel', frequency_Hz: Optional[float],
self._write_channel(f'sour{"{0}"}:tri:coun {repetitions}')
self._set_triggering()

def __exit__(self, exc_type, exc_val, exc_tb):
self.abort()
super()._cleanup('tri')
# Propagate exceptions
return False

def start(self) -> None:
"""Start the triangle wave generator
"""
Expand Down Expand Up @@ -923,6 +986,12 @@ def __init__(self, channel: 'QDac2Channel', trace_name: str,
self._write_channel(f'sour{"{0}"}:awg:coun {repetitions}')
self._set_triggering()

def __exit__(self, exc_type, exc_val, exc_tb):
self.abort()
super()._cleanup('awg')
# Propagate exceptions
return False

def start(self) -> None:
"""Start the AWG
"""
Expand Down
40 changes: 20 additions & 20 deletions qcodes_contrib_drivers/sims/QDAC2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -468,56 +468,56 @@ devices:
setter:
q: "sour{ch_id}:dc:mark:end {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
dc_mark_start:
default: 1
setter:
q: "sour{ch_id}:dc:mark:star {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
dc_mark_pend:
default: 1
setter:
q: "sour{ch_id}:dc:mark:send {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
dc_mark_pstart:
default: 1
setter:
q: "sour{ch_id}:dc:mark:sst {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
square_mark_end:
default: 1
setter:
q: "sour{ch_id}:squ:mark:end {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
square_mark_start:
default: 1
setter:
q: "sour{ch_id}:squ:mark:star {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
square_mark_pend:
default: 1
setter:
q: "sour{ch_id}:squ:mark:pend {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
square_mark_pstart:
default: 1
setter:
q: "sour{ch_id}:squ:mark:pstart {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
square_init_continuous:
default: "on"
Expand All @@ -531,28 +531,28 @@ devices:
setter:
q: "sour{ch_id}:sine:mark:end {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
sine_mark_start:
default: 1
setter:
q: "sour{ch_id}:sine:mark:star {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
sine_mark_pend:
default: 1
setter:
q: "sour{ch_id}:sine:mark:pend {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
sine_mark_pstart:
default: 1
setter:
q: "sour{ch_id}:sine:mark:pstart {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
sine_init_continuous:
default: "on"
Expand All @@ -566,28 +566,28 @@ devices:
setter:
q: "sour{ch_id}:tri:mark:end {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
triangle_mark_start:
default: 1
setter:
q: "sour{ch_id}:tri:mark:star {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
triangle_mark_pend:
default: 1
setter:
q: "sour{ch_id}:tri:mark:pend {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
triangle_mark_pstart:
default: 1
setter:
q: "sour{ch_id}:tri:mark:pstart {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
triangle_init_continuous:
default: "on"
Expand All @@ -601,28 +601,28 @@ devices:
setter:
q: "sour{ch_id}:awg:mark:end {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
awg_mark_start:
default: 1
setter:
q: "sour{ch_id}:awg:mark:star {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
awg_mark_pend:
default: 1
setter:
q: "sour{ch_id}:awg:mark:pend {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
awg_mark_pstart:
default: 1
setter:
q: "sour{ch_id}:awg:mark:pstart {}"
specs:
valid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
valid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
type: int
awg_init_continuous:
default: "on"
Expand Down
99 changes: 99 additions & 0 deletions qcodes_contrib_drivers/tests/QDevil/test_sim_qdac2_source_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,102 @@ def test_list_get_voltages(qdac): # noqa
# f'sour1:dc:trig:sour int{trigger.value}',
# 'sour1:dc:init',
# ]


def test_list_cleanup_triggering_on_exit(qdac): # noqa
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:trig:sour imm'
]


def test_list_main_trigger_is_deallocated_on_exit(qdac): # noqa
qdac._set_up_internal_triggers()
trigger = qdac.allocate_trigger()
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
dc_list.start_on(trigger)
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:trig:sour imm'
]
assert trigger.value in qdac._internal_triggers


def test_list_main_trigger_external_is_dismissed_on_exit(qdac): # noqa
trigger = ExternalInput(2)
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
dc_list.start_on_external(trigger)
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:trig:sour imm'
]


def test_list_start_marker_is_removed_on_exit(qdac): # noqa
qdac._set_up_internal_triggers()
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
trigger = dc_list.start_marker()
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:mark:star 0',
'sour1:dc:trig:sour imm'
]
assert trigger.value in qdac._internal_triggers


def test_list_end_marker_is_removed_on_exit(qdac): # noqa
qdac._set_up_internal_triggers()
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
trigger = dc_list.end_marker()
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:mark:end 0',
'sour1:dc:trig:sour imm'
]
assert trigger.value in qdac._internal_triggers


def test_list_step_start_marker_is_removed_on_exit(qdac): # noqa
qdac._set_up_internal_triggers()
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
trigger = dc_list.step_start_marker()
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:mark:sst 0',
'sour1:dc:trig:sour imm'
]
assert trigger.value in qdac._internal_triggers


def test_list_step_end_marker_is_removed_on_exit(qdac): # noqa
qdac._set_up_internal_triggers()
# -----------------------------------------------------------------------
with qdac.ch01.dc_list(voltages=range(1, 5)) as dc_list:
trigger = dc_list.step_end_marker()
qdac.start_recording_scpi()
# -----------------------------------------------------------------------
assert qdac.get_recorded_scpi_commands() == [
'sour1:dc:abor',
'sour1:dc:mark:send 0',
'sour1:dc:trig:sour imm'
]
assert trigger.value in qdac._internal_triggers
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,6 @@ def test_sweep_get_voltages(qdac): # noqa
voltages = dc_sweep.values_V()
# -----------------------------------------------------------------------
assert voltages == [-1.23, 0, 1.23]


# Here could be the same deallocaction tests as in dc_list.
Loading