diff --git a/docs/examples/driver_examples/Qcodes example with Keysight N9030B.ipynb b/docs/examples/driver_examples/Qcodes example with Keysight N9030B.ipynb new file mode 100644 index 000000000000..c135b3ba91f1 --- /dev/null +++ b/docs/examples/driver_examples/Qcodes example with Keysight N9030B.ipynb @@ -0,0 +1,366 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Qcodes example with Keysight N9030B" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook shows how to use Keysight N9030B instrument driver in Spectrum Analyzer and Phase Noise Modes for Swept SA and Log Plot measurements respectively.\n", + "\n", + "Let's begin!" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2021-01-14T15:11:25.180448Z", + "start_time": "2021-01-14T15:11:21.379687Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os\n", + "from qcodes.dataset import initialise_or_create_database_at, load_or_create_experiment, Measurement\n", + "from qcodes.dataset.plotting import plot_dataset, plot_by_id\n", + "\n", + "from qcodes.instrument_drivers.Keysight.N9030B import N9030B" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: Keysight Technologies N9030B (serial:MY56320646, firmware:A.24.57) in 0.35s\n" + ] + } + ], + "source": [ + "driver = N9030B(\"n9030b\",\"driver_address\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'vendor': 'Keysight Technologies',\n", + " 'model': 'N9030B',\n", + " 'serial': 'MY56320646',\n", + " 'firmware': 'A.24.57'}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "driver.IDN()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Spectrum Analyzer mode with Swept SA measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "sa = driver.sa" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "sa.setup_swept_sa_sweep(start=200, stop= 10e3, npts=20001)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### With QCoDeS Measurement" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize database and begin experiment..." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Upgrading database; v0 -> v1: : 0it [00:00, ?it/s]\n", + "Upgrading database; v1 -> v2: 100%|█████████████████████████████████████████████████████| 1/1 [00:00<00:00, 334.71it/s]\n", + "Upgrading database; v2 -> v3: : 0it [00:00, ?it/s]\n", + "Upgrading database; v3 -> v4: : 0it [00:00, ?it/s]\n", + "Upgrading database; v4 -> v5: 100%|█████████████████████████████████████████████████████| 1/1 [00:00<00:00, 167.42it/s]\n", + "Upgrading database; v5 -> v6: : 0it [00:00, ?it/s]\n", + "Upgrading database; v6 -> v7: 100%|██████████████████████████████████████████████████████| 1/1 [00:00<00:00, 91.64it/s]\n", + "Upgrading database; v7 -> v8: 100%|█████████████████████████████████████████████████████| 1/1 [00:00<00:00, 202.59it/s]\n", + "Upgrading database; v8 -> v9: 100%|█████████████████████████████████████████████████████| 1/1 [00:00<00:00, 202.59it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "tutorial_exp#no sample#1@C:\\Users\\asic\\Documents\\tutorial.db\n", + "------------------------------------------------------------" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tutorial_db_path = os.path.join(os.getcwd(), 'tutorial.db')\n", + "initialise_or_create_database_at(tutorial_db_path)\n", + "load_or_create_experiment(experiment_name='tutorial_exp', sample_name=\"no sample\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "meas1 = Measurement()\n", + "meas1.register_parameter(sa.trace)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 1. \n" + ] + } + ], + "source": [ + "with meas1.run() as datasaver:\n", + " datasaver.add_result((sa.trace, sa.trace.get()))\n", + "\n", + "dataset = datasaver.dataset" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Plot data" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_dataset(dataset)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Phase Noise mode with Log Plot measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "pn = driver.pn" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "pn.setup_log_plot_sweep(start_offset=10, stop_offset=200, npts=1001)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### With QCoDeS Measurement" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "meas2 = Measurement()\n", + "meas2.register_parameter(pn.trace)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting experimental run with id: 2. \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[n9030b_pn(PhaseNoiseMode)] Carrier(s) Incorrect or Missing!\n" + ] + } + ], + "source": [ + "with meas2.run() as datasaver:\n", + " datasaver.add_result((pn.trace, pn.trace.get()))\n", + "\n", + "run_id = datasaver.run_id" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Plot data" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "_ = plot_by_id(run_id)" + ] + }, + { + "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.7.9" + }, + "nbsphinx": { + "execute": "never" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/qcodes/instrument/sims/Keysight_N9030B.yaml b/qcodes/instrument/sims/Keysight_N9030B.yaml new file mode 100644 index 000000000000..e2586abb990c --- /dev/null +++ b/qcodes/instrument/sims/Keysight_N9030B.yaml @@ -0,0 +1,195 @@ +spec: "1.0" +devices: + KeysightN9030B: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*RST" + - q: ":ABORt" + - q: ":INSTrument:CATalog?" + r: '"SA 1, PNOISE 14"' + - q: ":CONFigure:CATalog?" + r: '"SAN, LPL"' + - q: "*OPT?" + r: '"544"' + - q: "*IDN?" + r: "Keysight Technologies,N9030B,1000,0.1" + + properties: + + mode: + default: "SA" + getter: + q: ":INSTrument:SELect?" + r: "{}" + setter: + q: ":INSTrument:SELect {}" + + measurement: + default: "SAN" + getter: + q: ":CONFigure?" + r: "{}" + setter: + q: ":CONFigure:{}" + + cont_meas: + getter: + q: ":INITiate:CONTinuous?" + r: "{}" + setter: + q: ":INITiate:CONTinuous {}" + + channels: + sa: + ids: ['sa'] + can_select: True + + properties: + + start: + default: 100 + getter: + q: ":SENSe:FREQuency:STARt?" + r: "{}" + setter: + q: ":SENSe:FREQuency:STARt {}" + specs: + type: float + + stop: + default: 10000 + getter: + q: ":SENSe:FREQuency:STOP?" + r: "{}" + setter: + q: ":SENSe:FREQuency:STOP {}" + specs: + type: float + + center: + default: 1.805e9 + getter: + q: ":SENSe:FREQuency:CENTer?" + r: "{}" + setter: + q: ":SENSe:FREQuency:CENTer {}" + specs: + type: float + + span: + default: 3.59e9 + getter: + q: ":SENSe:FREQuency:SPAN?" + r: "{}" + setter: + q: ":SENSe:FREQuency:SPAN {}" + specs: + type: float + + npts: + default: 1001 + getter: + q: ":SENSe:SWEep:POINts?" + r: "{}" + setter: + q: ":SENSe:SWEep:POINts {}" + specs: + min: 1 + max: 20001 + type: int + + sweep_time: + default: 20 + getter: + q: ":SENSe:SWEep:TIME?" + r: "{}" + specs: + type: float + + auto_sweep_time_enabled: + default: "ON" + getter: + q: ":SENSe:SWEep:TIME:AUTO?" + r: "{}" + setter: + q: ":SENSe:SWEep:TIME:AUTO {}" + specs: + type: str + valid: ["ON", "OFF"] + + auto_sweep_type_enabled: + default: "OFF" + getter: + q: ":SENSe:SWEep:TYPE:AUTO?" + r: "{}" + setter: + q: ":SENSe:SWEep:TYPE:AUTO {}" + specs: + type: str + valid: ["ON", "OFF"] + + sweep_type: + default: "SWE" + getter: + q: ":SENSe:SWEep:TYPE?" + r: "{}" + setter: + q: ":SENSe:SWEep:TYPE {}" + specs: + type: str + valid: ["FFT", "SWE"] + pn: + ids: ['pn'] + can_select: True + + properties: + npts: + default: 601 + getter: + q: ":SENSe:LPLot:SWEep:POINts?" + r: "{}" + setter: + q: ":SENSe:LPLot:SWEep:POINts {}" + specs: + min: 601 + max: 20001 + type: int + + start_offset: + default: 100 + getter: + q: ":SENSe:LPLot:FREQuency:OFFSet:STARt?" + r: "{}" + setter: + q: ":SENSe:LPLot:FREQuency:OFFSet:STARt {}" + specs: + type: float + + stop_offset: + default: 1e6 + getter: + q: ":SENSe:LPLot:FREQuency:OFFSet:STOP?" + r: "{}" + setter: + q: ":SENSe:LPLot:FREQuency:OFFSet:STOP {}" + specs: + type: float + + signal_tracking_enabled: + default: "ON" + getter: + q: ":SENSe:FREQuency:CARRier:TRACk?" + r: "{}" + setter: + q: ":SENSe:FREQuency:CARRier:TRACk {}" + specs: + type: str + valid: ["ON", "OFF"] + +resources: + GPIB::1::INSTR: + device: KeysightN9030B diff --git a/qcodes/instrument_drivers/Keysight/N9030B.py b/qcodes/instrument_drivers/Keysight/N9030B.py new file mode 100644 index 000000000000..a4cc303203c7 --- /dev/null +++ b/qcodes/instrument_drivers/Keysight/N9030B.py @@ -0,0 +1,610 @@ +import numpy as np +from typing import Any, Tuple, Dict, Union + +from qcodes import ( + VisaInstrument, InstrumentChannel, Parameter, ParameterWithSetpoints +) +from qcodes.instrument.parameter import ParamRawDataType +from qcodes.utils.validators import Enum, Numbers, Arrays, Ints +from qcodes.utils.helpers import create_on_off_val_mapping + + +class FrequencyAxis(Parameter): + + def __init__(self, + start: Parameter, + stop: Parameter, + npts: Parameter, + *args: Any, + **kwargs: Any + ) -> None: + super().__init__(*args, **kwargs) + self._start: Parameter = start + self._stop: Parameter = stop + self._npts: Parameter = npts + + def get_raw(self) -> ParamRawDataType: + return np.linspace(self._start(), self._stop(), self._npts()) + + +class Trace(ParameterWithSetpoints): + + def __init__(self, number: int, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.instrument: Union["SpectrumAnalyzerMode", "PhaseNoiseMode"] + self.root_instrument: "N9030B" + + self.number = number + + def get_raw(self) -> ParamRawDataType: + return self.instrument._get_data(trace_num=self.number) + + +class SpectrumAnalyzerMode(InstrumentChannel): + """ + Spectrum Analyzer Mode for Keysight N9030B instrument. + """ + + def __init__(self, parent: "N9030B", name: str, *arg: Any, **kwargs: Any): + super().__init__(parent, name, *arg, **kwargs) + + self._min_freq = -8e7 + self._valid_max_freq: Dict[str, float] = {"503": 3.7e9, + "508": 8.5e9, + "513": 13.8e9, + "526": 27e9, + "544": 44.5e9} + opt: str + for hw_opt_for_max_freq in self._valid_max_freq.keys(): + if hw_opt_for_max_freq in self.root_instrument._options(): + opt = hw_opt_for_max_freq + self._max_freq = self._valid_max_freq[opt] + + self.add_parameter( + name="start", + unit="Hz", + get_cmd=":SENSe:FREQuency:STARt?", + set_cmd=self._set_start, + get_parser=float, + vals=Numbers(self._min_freq, self._max_freq - 10), + docstring="start frequency for the sweep" + ) + + self.add_parameter( + name="stop", + unit="Hz", + get_cmd=":SENSe:FREQuency:STOP?", + set_cmd=self._set_stop, + get_parser=float, + vals=Numbers(self._min_freq + 10, self._max_freq), + docstring="stop frequency for the sweep" + ) + + self.add_parameter( + name="center", + unit="Hz", + get_cmd=":SENSe:FREQuency:CENTer?", + set_cmd=self._set_center, + get_parser=float, + vals=Numbers(self._min_freq + 5, self._max_freq - 5), + docstring="Sets and gets center frequency" + ) + + self.add_parameter( + name="span", + unit="Hz", + get_cmd=":SENSe:FREQuency:SPAN?", + set_cmd=self._set_span, + get_parser=float, + vals=Numbers(10, self._max_freq - self._min_freq), + docstring="Changes span of frequency" + ) + + self.add_parameter( + name="npts", + get_cmd=":SENSe:SWEep:POINts?", + set_cmd=self._set_npts, + get_parser=int, + vals=Ints(1, 20001), + docstring="Number of points for the sweep" + ) + + self.add_parameter( + name="sweep_time", + label="Sweep time", + get_cmd=":SENSe:SWEep:TIME?", + set_cmd=":SENSe:SWEep:TIME {}", + get_parser=float, + unit="s", + docstring="gets sweep time" + ) + + self.add_parameter( + name="auto_sweep_time_enabled", + get_cmd=":SENSe:SWEep:TIME:AUTO?", + set_cmd=self._enable_auto_sweep_time, + val_mapping=create_on_off_val_mapping(on_val="ON", off_val="OFF"), + docstring="enables auto sweep time" + ) + + self.add_parameter( + name="auto_sweep_type_enabled", + get_cmd=":SENSe:SWEep:TYPE:AUTO?", + set_cmd=self._enable_auto_sweep_type, + val_mapping=create_on_off_val_mapping(on_val="ON", off_val="OFF"), + docstring="enables auto sweep type" + ) + + self.add_parameter( + name="sweep_type", + get_cmd=":SENSe:SWEep:TYPE?", + set_cmd=self._set_sweep_type, + val_mapping={ + "fft": "FFT", + "sweep": "SWE", + }, + docstring="Sets up sweep type. Possible options are 'fft' and " + "'sweep'." + ) + + self.add_parameter( + name="freq_axis", + label="Frequency", + unit="Hz", + start=self.start, + stop=self.stop, + npts=self.npts, + vals=Arrays(shape=(self.npts.get_latest,)), + parameter_class=FrequencyAxis, + docstring="Creates frequency axis for the sweep from start, " + "stop and npts values." + ) + + self.add_parameter( + name="trace", + label="Trace", + unit="dB", + number=1, + vals=Arrays(shape=(self.npts.get_latest,)), + setpoints=(self.freq_axis,), + parameter_class=Trace, + docstring="Gets trace data." + ) + + def _set_start(self, val: float) -> None: + """ + Sets start frequency + """ + stop = self.stop() + if val >= stop: + raise ValueError(f"Start frequency must be smaller than stop " + f"frequency. Provided start freq is: {val} Hz and " + f"set stop freq is: {stop} Hz") + + self.write(f":SENSe:FREQuency:STARt {val}") + + start = self.start() + if abs(val - start) >= 1: + self.log.warning( + f"Could not set start to {val} setting it to {start}" + ) + + def _set_stop(self, val: float) -> None: + """ + Sets stop frequency + """ + start = self.start() + if val <= start: + raise ValueError(f"Stop frequency must be larger than start " + f"frequency. Provided stop freq is: {val} Hz and " + f"set start freq is: {start} Hz") + + self.write(f":SENSe:FREQuency:STOP {val}") + + stop = self.stop() + if abs(val - stop) >= 1: + self.log.warning( + f"Could not set stop to {val} setting it to {stop}" + ) + + def _set_center(self, val: float) -> None: + """ + Sets center frequency and updates start and stop frequencies if they + change. + """ + self.write(f":SENSe:FREQuency:CENTer {val}") + self.update_trace() + + def _set_span(self, val: float) -> None: + """ + Sets frequency span and updates start and stop frequencies if they + change. + """ + self.write(f":SENSe:FREQuency:SPAN {val}") + self.update_trace() + + def _set_npts(self, val: int) -> None: + """ + Sets number of points for sweep + """ + self.write(f":SENSe:SWEep:POINts {val}") + + def _enable_auto_sweep_time(self, val: str) -> None: + """ + Enables auto sweep time + """ + self.write(f":SENSe:SWEep:TIME:AUTO {val}") + + def _enable_auto_sweep_type(self, val: str) -> None: + """ + Enables auto sweep type + """ + self.write(f":SENSe:SWEep:TYPE:AUTO {val}") + + def _set_sweep_type(self, val: str) -> None: + """ + Sets sweep type + """ + self.write(f":SENSe:SWEep:TYPE {val}") + + def _get_data(self, trace_num: int) -> ParamRawDataType: + """ + Gets data from the measurement. + """ + try: + timeout = self.sweep_time() + self.root_instrument._additional_wait + with self.root_instrument.timeout.set_to(timeout): + data_str = self.ask(f":READ:" + f"{self.root_instrument.measurement()}" + f"{trace_num}?") + data = np.array(data_str.rstrip().split(",")).astype("float64") + except TimeoutError as e: + raise TimeoutError("Couldn't receive any data. Command timed " + "out.") from e + + trace_data = data[1::2] + return trace_data + + def update_trace(self) -> None: + """ + Updates start and stop frequencies whenever span of/or center frequency + is updated. + """ + self.start() + self.stop() + + def setup_swept_sa_sweep(self, + start: float, + stop: float, + npts: int) -> None: + """ + Sets up the Swept SA measurement sweep for Spectrum Analyzer Mode. + """ + self.root_instrument.mode("SA") + if "SAN" in self.root_instrument._available_meas(): + self.root_instrument.measurement("SAN") + else: + raise RuntimeError("Swept SA measurement is not available on your " + "Keysight N9030B instrument with Spectrum " + "Analyzer mode.") + self.start(start) + self.stop(stop) + self.npts(npts) + + def autotune(self) -> None: + """ + Autotune quickly get to the most likely signal of interest, and + position it optimally on the display. + """ + self.write(":SENS:FREQuency:TUNE:IMMediate") + self.center() + + +class PhaseNoiseMode(InstrumentChannel): + """ + Phase Noise Mode for Keysight N9030B instrument. + """ + + def __init__(self, parent: "N9030B", name: str, *arg: Any, **kwargs: Any): + super().__init__(parent, name, *arg, **kwargs) + + self._min_freq = 1 + self._valid_max_freq: Dict[str, float] = {"503": 3699999995, + "508": 8499999995, + "513": 13799999995, + "526": 26999999995, + "544": 44499999995} + opt: str + for hw_opt_for_max_freq in self._valid_max_freq.keys(): + if hw_opt_for_max_freq in self.root_instrument._options(): + opt = hw_opt_for_max_freq + self._max_freq = self._valid_max_freq[opt] + + self.add_parameter( + name="npts", + get_cmd=":SENSe:LPLot:SWEep:POINts?", + set_cmd=":SENSe:LPLot:SWEep:POINts {}", + get_parser=int, + vals=Ints(601, 20001), + docstring="Number of points for the sweep" + ) + + self.add_parameter( + name="start_offset", + unit="Hz", + get_cmd=":SENSe:LPLot:FREQuency:OFFSet:STARt?", + set_cmd=self._set_start_offset, + get_parser=float, + vals=Numbers(self._min_freq, self._max_freq - 10), + docstring="start frequency offset for the plot" + ) + + self.add_parameter( + name="stop_offset", + unit="Hz", + get_cmd=":SENSe:LPLot:FREQuency:OFFSet:STOP?", + set_cmd=self._set_stop_offset, + get_parser=float, + vals=Numbers(self._min_freq + 99, self._max_freq), + docstring="stop frequency offset for the plot" + ) + + self.add_parameter( + name="signal_tracking_enabled", + get_cmd=":SENSe:FREQuency:CARRier:TRACk?", + set_cmd=":SENSe:FREQuency:CARRier:TRACk {}", + val_mapping=create_on_off_val_mapping(on_val="ON", off_val="OFF"), + docstring="Gets/Sets signal tracking. When signal tracking is " + "enabled carrier signal is repeatedly realigned. Signal " + "Tracking assumes the new acquisition occurs repeatedly " + "without pause." + ) + + self.add_parameter( + name="freq_axis", + label="Frequency", + unit="Hz", + start=self.start_offset, + stop=self.stop_offset, + npts=self.npts, + vals=Arrays(shape=(self.npts.get_latest,)), + parameter_class=FrequencyAxis, + docstring="Creates frequency axis for the sweep from " + "start_offset, stop_offset and npts values." + ) + + self.add_parameter( + name="trace", + label="Trace", + unit="dB", + number=3, + vals=Arrays(shape=(self.npts.get_latest,)), + setpoints=(self.freq_axis,), + parameter_class=Trace, + docstring="Gets trace data." + ) + + def _set_start_offset(self, val: float) -> None: + """ + Sets start offset for frequency in the plot + """ + stop_offset = self.stop_offset() + self.write(f":SENSe:LPLot:FREQuency:OFFSet:STARt {val}") + start_offset = self.start_offset() + + if abs(val - start_offset) >= 1: + self.log.warning( + f"Could not set start offset to {val} setting it to " + f"{start_offset}" + ) + if val >= stop_offset or abs(val - stop_offset) < 10: + self.log.warning(f"Provided start frequency offset {val} Hz was " + f"greater than preset stop frequency offset " + f"{stop_offset} Hz. Provided start frequency " + f"offset {val} Hz is set and new stop freq offset" + f" is: {self.stop_offset()} Hz.") + + def _set_stop_offset(self, val: float) -> None: + """ + Sets stop offset for frequency in the plot + """ + start_offset = self.start_offset() + self.write(f":SENSe:LPLot:FREQuency:OFFSet:STOP {val}") + stop_offset = self.stop_offset() + + if abs(val - stop_offset) >= 1: + self.log.warning( + f"Could not set stop offset to {val} setting it to " + f"{stop_offset}" + ) + + if val <= start_offset or abs(val-start_offset) < 10: + self.log.warning(f"Provided stop frequency offset {val} Hz was " + f"less than preset start frequency offset " + f"{start_offset} Hz. Provided stop frequency " + f"offset {val} Hz is set and new start freq offset" + f" is: {self.start_offset()} Hz.") + + def _get_data(self, trace_num: int) -> ParamRawDataType: + """ + Gets data from the measurement. + """ + raw_data = self.ask(f":READ:{self.root_instrument.measurement()}{1}?") + trace_res_details = np.array( + raw_data.rstrip().split(",") + ).astype("float64") + + if len(trace_res_details) != 7 or ( + len(trace_res_details) >= 1 and trace_res_details[0] < -50 + ): + self.log.warning("Carrier(s) Incorrect or Missing!") + return -1 * np.ones(self.npts()) + + try: + data_str = self.ask(f":READ:{self.root_instrument.measurement()}" + f"{trace_num}?") + data = np.array(data_str.rstrip().split(",")).astype("float64") + except TimeoutError as e: + raise TimeoutError("Couldn't receive any data. Command timed " + "out.") from e + + trace_data = data[1::2] + return trace_data + + def setup_log_plot_sweep(self, + start_offset: float, + stop_offset: float, + npts: int + ) -> None: + """ + Sets up the Log Plot measurement sweep for Phase Noise Mode. + """ + self.root_instrument.mode("PNOISE") + if "LPL" in self.root_instrument._available_meas(): + self.root_instrument.measurement("LPL") + else: + raise RuntimeError("Log Plot measurement is not available on your " + "Keysight N9030B instrument with Phase Noise " + "mode.") + + self.start_offset(start_offset) + self.stop_offset(stop_offset) + self.npts(npts) + + def autotune(self) -> None: + """ + On autotune, the measurement automatically searches for and tunes to + the strongest signal in the full span of the analyzer. + """ + self.write(":SENSe:FREQuency:CARRier:SEARch") + self.start_offset() + self.stop_offset() + + +class N9030B(VisaInstrument): + """ + Driver for Keysight N9030B PXA signal analyzer. Keysight N9030B PXA + siganl analyzer is part of Keysight X-Series Multi-touch Signal + Analyzers. + This driver allows Swept SA measurements in Spectrum Analyzer mode and + Log Plot measurements in Phase Noise mode of the instrument. + + Args: + name + address + """ + + def __init__(self, name: str, address: str, **kwargs: Any) -> None: + super().__init__(name, address, terminator='\n', **kwargs) + + self._min_freq: float + self._max_freq: float + self._additional_wait: float = 1 + + self.add_parameter( + name="mode", + get_cmd=":INSTrument:SELect?", + set_cmd=":INSTrument:SELect {}", + vals=Enum(*self._available_modes()), + docstring="Allows setting of different modes present and licensed " + "for the instrument." + ) + + self.add_parameter( + name="measurement", + get_cmd=":CONFigure?", + set_cmd=":CONFigure:{}", + vals=Enum("SAN", "LPL"), + docstring="Sets measurement type from among the available " + "measurement types." + ) + + self.add_parameter( + name="cont_meas", + initial_value=False, + get_cmd=":INITiate:CONTinuous?", + set_cmd=self._enable_cont_meas, + val_mapping=create_on_off_val_mapping(on_val="ON", off_val="OFF"), + docstring="Enables or disables continuous measurement." + ) + + self.add_parameter( + name="format", + get_cmd=":FORMat:TRACe:DATA?", + set_cmd=":FORMat:TRACe:DATA {}", + val_mapping={ + "ascii": "ASCii", + "int32": "INTeger,32", + "real32": "REAL,32", + "real64": "REAL,64" + }, + docstring="Sets up format of data received" + ) + + if "SA" in self._available_modes(): + sa_mode = SpectrumAnalyzerMode(self, name="sa") + self.add_submodule("sa", sa_mode) + else: + self.log.info("Spectrum Analyzer mode is not available on this " + "instrument.") + + if "PNOISE" in self._available_modes(): + pnoise_mode = PhaseNoiseMode(self, name="pn") + self.add_submodule("pn", pnoise_mode) + else: + self.log.info("Phase Noise mode is not available on this " + "instrument.") + self.connect_message() + + def _available_modes(self) -> Tuple[str, ...]: + """ + Returns present and licensed modes for the instrument. + """ + available_modes = self.ask(":INSTrument:CATalog?") + av_modes = available_modes[1:-1].split(',') + modes: Tuple[str, ...] = () + for i, mode in enumerate(av_modes): + if i == 0: + modes = modes + (mode.split(' ')[0], ) + else: + modes = modes + (mode.split(' ')[1], ) + return modes + + def _available_meas(self) -> Tuple[str, ...]: + """ + Gives available measurement with a given mode for the instrument + """ + available_meas = self.ask(":CONFigure:CATalog?") + av_meas = available_meas[1:-1].split(',') + measurements: Tuple[str, ...] = () + for i, meas in enumerate(av_meas): + if i == 0: + measurements = measurements + (meas, ) + else: + measurements = measurements + (meas[1:], ) + return measurements + + def _enable_cont_meas(self, val: str) -> None: + """ + Sets continuous measurement to ON or OFF. + """ + self.write(f":INITiate:CONTinuous {val}") + + def _options(self) -> Tuple[str, ...]: + """ + Returns installed options numbers. + """ + options_raw = self.ask('*OPT?') + return tuple(options_raw[1:-1].split(',')) + + def reset(self) -> None: + """ + Reset the instrument by sending the RST command + """ + self.write("*RST") + + def abort(self) -> None: + """ + Aborts the measurement + """ + self.write(":ABORt") diff --git a/qcodes/tests/drivers/test_keysight_n9030b.py b/qcodes/tests/drivers/test_keysight_n9030b.py new file mode 100644 index 000000000000..c54d24d37800 --- /dev/null +++ b/qcodes/tests/drivers/test_keysight_n9030b.py @@ -0,0 +1,56 @@ +import pytest + +from qcodes.instrument_drivers.Keysight.N9030B import (N9030B, + SpectrumAnalyzerMode, + PhaseNoiseMode) +import qcodes.instrument.sims as sims + +VISALIB = sims.__file__.replace('__init__.py', 'Keysight_N9030B.yaml@sim') + + +@pytest.fixture(name="driver") +def _make_driver(): + driver = N9030B('n9030B_sim', address="GPIB::1::INSTR", visalib=VISALIB) + yield driver + driver.close() + + +@pytest.fixture(name="sa") +def _activate_swept_sa_measurement(driver): + yield driver.sa + + +@pytest.fixture(name="pn") +def _activate_log_plot_measurement(driver): + yield driver.pn + + +def test_idn(driver): + assert {'firmware': '0.1', + 'model': 'N9030B', + 'serial': '1000', + 'vendor': 'Keysight Technologies'} == driver.IDN() + + +def test_swept_sa_setup(sa): + assert isinstance(sa, SpectrumAnalyzerMode) + + sa.setup_swept_sa_sweep(123, 11e3, 501) + assert sa.root_instrument.mode() == "SA" + assert sa.root_instrument.measurement() == "SAN" + + assert sa.start() == 123 + assert sa.stop() == 11e3 + assert sa.npts() == 501 + + +def test_log_plot_setup(pn): + assert isinstance(pn, PhaseNoiseMode) + + pn.setup_log_plot_sweep(1000, 1e7, 10001) + assert pn.root_instrument.mode() == "PNOISE" + assert pn.root_instrument.measurement() == "LPL" + + assert pn.start_offset() == 1000 + assert pn.stop_offset() == 1e7 + assert pn.npts() == 10001