Source code for zhinst.toolkit.driver.devices.shfsg
"""SHFSG Instrument Driver."""
import logging
import typing as t
import zhinst.utils.shfsg as utils
from zhinst.toolkit.driver.devices.base import BaseInstrument
from zhinst.toolkit.driver.nodes.awg import AWG
from zhinst.toolkit.nodetree import Node
from zhinst.toolkit.nodetree.helper import lazy_property, not_callable_in_transactions
from zhinst.toolkit.nodetree.node import NodeList
logger = logging.getLogger(__name__)
if t.TYPE_CHECKING: # pragma: no cover
from zhinst.toolkit.session import Session
[docs]class AWGCore(AWG):
"""AWG Core Node."""
[docs] def configure_marker_and_trigger(
self,
*,
trigger_in_source: str,
trigger_in_slope: str,
marker_out_source: str,
) -> None:
"""Configures the trigger inputs and marker outputs of the AWG.
Args:
trigger_in_source: Alias for the trigger input used by the
sequencer. For a list of available values use:
`available_trigger_inputs`
trigger_in_slope: Alias for the slope of the input trigger
used by sequencer. For a list of available values use
`available_trigger_inputs`
marker_out_source: Alias for the marker output source used by
the sequencer. For a list of available values use
`available_trigger_slopes`
"""
settings = utils.get_marker_and_trigger_settings(
self._serial,
self._index,
trigger_in_source=trigger_in_source,
trigger_in_slope=trigger_in_slope,
marker_out_source=marker_out_source,
)
self._send_set_list(settings)
@property
def available_trigger_inputs(self) -> t.List[str]:
"""List the available trigger sources for the sequencer."""
return [
option.enum
for option in self.auxtriggers[0].channel.node_info.options.values()
]
@property
def available_trigger_slopes(self) -> t.List[str]:
"""List the available trigger slopes for the sequencer."""
return [
option.enum
for option in self.auxtriggers[0].slope.node_info.options.values()
]
@property
def available_marker_outputs(self) -> t.List[str]:
"""List the available trigger marker outputs for the sequencer."""
return [
option.enum
for option in self.root.sgchannels[
self._index
].marker.source.node_info.options.values()
]
[docs]class SGChannel(Node):
"""Signal Generator Channel for the SHFSG.
:class:`SGChannel` implements basic functionality to configure SGChannel
settings of the :class:`SHFSG` instrument.
Args:
device: SHFQA device object.
session: Underlying session.
tree: Node tree (node path as tuple) of the corresponding node.
"""
def __init__(
self,
device: "SHFSG",
session: "Session",
tree: t.Tuple[str, ...],
):
super().__init__(device.root, tree)
self._index = int(tree[-1])
self._device = device
self._serial = device.serial
self._session = session
[docs] @not_callable_in_transactions
def configure_channel(
self,
*,
enable: bool,
output_range: int,
center_frequency: float,
rf_path: bool,
) -> None:
"""Configures the RF input and output.
Args:
enable: Flag if the signal output should be enabled.
output_range: Maximal range of the signal output power in dBm
center_frequency: Center frequency before modulation
rf_path: Flag if the RF(True) or LF(False) path should be
configured.
"""
utils.configure_channel(
self._session.daq_server,
self._device.serial,
self._index,
enable=int(enable),
output_range=output_range,
center_frequency=center_frequency,
rflf_path=int(rf_path),
)
[docs] def configure_pulse_modulation(
self,
*,
enable: bool,
osc_index: int = 0,
osc_frequency: float = 100e6,
phase: float = 0.0,
global_amp: float = 0.5,
gains: tuple = (1.0, -1.0, 1.0, 1.0),
sine_generator_index: int = 0,
) -> None:
"""Configure the pulse modulation.
Configures the sine generator to digitally modulate the AWG output, for
generating single sideband AWG signals
Args:
enable: Flag if the modulation should be enabled.
osc_index: Selects which oscillator to use
osc_frequency: Oscillator frequency used to modulate the AWG
outputs. (default = 100e6)
phase: Sets the oscillator phase. (default = 0.0)
global_amp: Global scale factor for the AWG outputs. (default = 0.5)
gains: Sets the four amplitudes used for single sideband generation.
Default values correspond to upper sideband with a positive
oscillator frequency. (default = (1.0, -1.0, 1.0, 1.0))
sine_generator_index: Selects which sine generator to use on a
given channel.
"""
settings = utils.get_pulse_modulation_settings(
self._device.serial,
self._index,
enable=int(enable),
osc_index=osc_index,
osc_frequency=osc_frequency,
phase=phase,
global_amp=global_amp,
gains=gains,
sine_generator_index=sine_generator_index,
)
self._send_set_list(settings)
[docs] def configure_sine_generation(
self,
*,
enable: bool,
osc_index: int = 0,
osc_frequency: float = 100e6,
phase: float = 0.0,
gains: tuple = (0.0, 1.0, 1.0, 0.0),
sine_generator_index: int = 0,
) -> None:
"""Configures the sine generator output.
Configures the sine generator output of a specified channel for generating
continuous wave signals without the AWG.
Args:
enable: Flag if the sine generator output should be enabled.
osc_index: Selects which oscillator to use
osc_frequency: Oscillator frequency used by the sine generator
(default = 100e6)
phase: Sets the oscillator phase. (default = 0.0)
gains: Sets the four amplitudes used for single sideband
generation. Default values correspond to upper sideband with a
positive oscillator frequency.
Gains are set in the following order I/sin, I/cos, Q/sin, Q/cos.
(default = (0.0, 1.0, 1.0, 0.0))
sine_generator_index: Selects which sine generator to use on a given
channel
"""
settings = utils.get_sine_generation_settings(
self._device.serial,
self._index,
enable=int(enable),
osc_index=osc_index,
osc_frequency=osc_frequency,
phase=phase,
gains=gains,
sine_generator_index=sine_generator_index,
)
self._send_set_list(settings)
@property
def awg_modulation_freq(self) -> float:
"""Modulation frequency of the AWG.
Depends on the selected oscillator.
"""
selected_osc = self.sines[0].oscselect()
return self.oscs[selected_osc].freq()
@lazy_property
def awg(self) -> AWGCore:
"""AWG."""
return AWGCore(
self._root,
self._tree + ("awg",),
self._device.serial,
self._index,
self._device.device_type,
self._device.device_options,
)
[docs]class SHFSG(BaseInstrument):
"""High-level driver for the Zurich Instruments SHFSG."""
@lazy_property
def sgchannels(self) -> t.Sequence[SGChannel]:
"""A Sequence of SG Channels."""
return NodeList(
[
SGChannel(self, self._session, self._tree + ("sgchannels", str(i)))
for i in range(len(self["sgchannels"]))
],
self._root,
self._tree + ("sgchannels",),
)