├── utils ├── __init__.py └── python │ └── __init__.py ├── requirements-dev.txt ├── hidden ├── python │ ├── requirements_test.txt │ ├── pytest.ini │ ├── add_example_path.py │ ├── check_zhinst_version.py │ ├── coverage_report_profiles.txt │ ├── runner_examples.py │ ├── consistency_check_testspec.py │ ├── coverage_report.py │ ├── consistency_check_cli.py │ └── coverage_report_html.py ├── api_examples.code-workspace ├── .vscode │ ├── README_VSCODE_LAUNCH.md │ ├── settings.json.template │ └── launch.json.template └── jupytext.md ├── .jupytext ├── requirements.txt ├── .gitignore ├── hdawg ├── matlab │ └── test.spec.yml └── python │ └── test.spec.yml ├── mf ├── matlab │ ├── test.spec.yml │ ├── example_poll_impedance.m │ └── example_autoranging_impedance.m └── python │ ├── test.spec.yml │ ├── example_autoranging_impedance.py │ └── example_poll_impedance.py ├── ziListExamples.m ├── uhf ├── matlab │ └── test.spec.yml └── python │ └── test.spec.yml ├── hf2 ├── matlab │ ├── test.spec.yml │ └── hf2_example_autorange.m └── python │ ├── test.spec.yml │ └── example_connect.md ├── shfsg └── python │ ├── Ramsey_command_table.json │ ├── Rabi.seq │ ├── CPMG.seq │ ├── test.spec.yml │ ├── Rabi_command_table.json │ ├── CPMG_command_table.json │ ├── Ramsey.seq │ ├── example_sine.py │ ├── example_rabi.py │ ├── example_cpmg.py │ └── example_ramsey.py ├── ghfli ├── python │ └── test.spec.yml └── matlab │ ├── example_ghfli_sweeper.m │ ├── example_ghfli_triggered_data_acquisition.m │ └── example_ghfli_poll_data.m ├── shfli ├── python │ └── test.spec.yml └── matlab │ ├── example_shfli_sweeper.m │ ├── example_shfli_triggered_data_acquisition.m │ └── example_shfli_poll_data.m ├── uhfqa └── python │ ├── test.spec.yml │ ├── common_uhfqa.py │ └── example_monitor.py ├── shfqc └── python │ └── README.adoc ├── LICENSE ├── .gitattributes ├── shfqa └── python │ ├── test.spec.yml │ ├── helper_commons.py │ ├── example_resonator.md │ ├── example_resonator.py │ ├── helper_resonator.py │ ├── example_qubit_readout_measurement.py │ └── example_qubit_readout_weights.py ├── ziAddExamplePath.m ├── hf2-mf-uhf ├── python │ ├── example_connect.md │ ├── example_save_device_settings_simple.py │ ├── test.spec.yml │ ├── example_save_device_settings_expert.py │ └── example_connect_config.py └── matlab │ ├── example_connect.m │ ├── example_save_device_settings_simple.m │ ├── test.spec.yml │ ├── example_save_device_settings_expert.m │ └── example_connect_config.m ├── .gitlab-ci.yml └── README.adoc /utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /utils/python/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | black==24.10.0 2 | -------------------------------------------------------------------------------- /hidden/python/requirements_test.txt: -------------------------------------------------------------------------------- 1 | pytest==5.3.2 2 | pyyaml==5.4.1 3 | zhinst -------------------------------------------------------------------------------- /.jupytext: -------------------------------------------------------------------------------- 1 | # Always pair ipynb notebooks to md files 2 | formats = "ipynb,md" 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | zhinst 3 | scipy 4 | lmfit 5 | matplotlib 6 | jupytext 7 | -------------------------------------------------------------------------------- /hidden/python/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | junit_family=xunit2 3 | 4 | # Pytest minimum version we require. 5 | minversion = 5.3.2 -------------------------------------------------------------------------------- /hidden/api_examples.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | } 6 | ], 7 | "settings": { 8 | } 9 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #python 2 | __pycache__ 3 | 4 | # VSCode 5 | .vscode/* 6 | 7 | # Mac 8 | .DS_Store 9 | 10 | # Jupyter Notebook 11 | **/*.ipynb 12 | **/*.ipynb_checkpoints 13 | -------------------------------------------------------------------------------- /hdawg/matlab/test.spec.yml: -------------------------------------------------------------------------------- 1 | hdawg_example_awg_commandtable: 2 | scenario_1: 3 | deviceparams: 4 | device_id: "HDAWG8" 5 | 6 | hdawg_example_awg_grouped_mode: 7 | scenario_1: 8 | deviceparams: 9 | device_id: "HDAWG8" -------------------------------------------------------------------------------- /mf/matlab/test.spec.yml: -------------------------------------------------------------------------------- 1 | example_poll_impedance: 2 | scenario_1: 3 | deviceparams: 4 | device_id: "MFIA" 5 | 6 | example_autoranging_impedance: 7 | scenario_1: 8 | deviceparams: 9 | device_id: "MFIA" 10 | -------------------------------------------------------------------------------- /hidden/.vscode/README_VSCODE_LAUNCH.md: -------------------------------------------------------------------------------- 1 | 2 | To enable this launch configuration: 3 | cp hidden/.vscode/launch.json.template .vscode/launch.json 4 | cp hidden/.vscode/settings.json.template .vscode/settings.json 5 | 6 | Note that the active '.vscode' directory is one directory up! 7 | -------------------------------------------------------------------------------- /ziListExamples.m: -------------------------------------------------------------------------------- 1 | function ziListExamples 2 | % ZILISTEXAMPLES lists all available examples in the api-examples project 3 | % 4 | % USAGE: 5 | % ziListExamples(); 6 | 7 | mfile = which(mfilename); 8 | [pathstr, ~] = fileparts(mfile); 9 | 10 | examples = dir([pathstr filesep '**/*example_*.m']); 11 | 12 | for example = examples.' 13 | disp(example.name) 14 | end 15 | end 16 | 17 | -------------------------------------------------------------------------------- /hidden/.vscode/settings.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.pytestArgs": [ 3 | "tests" 4 | ], 5 | "python.testing.unittestEnabled": false, 6 | "python.testing.nosetestsEnabled": false, 7 | "python.testing.pytestEnabled": true, 8 | "python.linting.enabled": true, 9 | "python.linting.pylintEnabled": true, 10 | "python.linting.mypyEnabled": false, 11 | } -------------------------------------------------------------------------------- /uhf/matlab/test.spec.yml: -------------------------------------------------------------------------------- 1 | uhf_example_awg: 2 | scenario_1: 3 | deviceparams: 4 | device_id: "UHFLI" 5 | options: ["AWG"] 6 | 7 | uhf_example_awg_sourcefile: 8 | scenario_1: 9 | deviceparams: 10 | device_id: "UHFLI" 11 | options: ["AWG"] 12 | 13 | uhf_example_boxcar: 14 | scenario_1: 15 | deviceparams: 16 | device_id: "UHFLI" 17 | options: ["BOX"] 18 | 19 | -------------------------------------------------------------------------------- /hidden/python/add_example_path.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import sys 3 | 4 | 5 | class add_example_path: 6 | def __init__(self, example: Path): 7 | self.example = example 8 | self.example_dir = example.resolve().parent 9 | 10 | def __enter__(self): 11 | sys.path.insert(0, str(self.example_dir)) 12 | 13 | def __exit__(self, type, value, traceback): 14 | sys.path.remove(str(self.example_dir)) 15 | -------------------------------------------------------------------------------- /hf2/matlab/test.spec.yml: -------------------------------------------------------------------------------- 1 | hf2_example_autorange: 2 | scenario_1: 3 | deviceparams: 4 | device_id: "HF2LI" 5 | 6 | hf2_example_pid_advisor_pll: 7 | scenario_1: 8 | deviceparams: 9 | device_id: "HF2LI" 10 | options: ["PLL"] 11 | 12 | hf2_example_poll_hardware_trigger: 13 | scenario_1: 14 | deviceparams: 15 | device_id: "HF2LI" 16 | 17 | hf2_example_scope: 18 | scenario_1: 19 | deviceparams: 20 | device_id: "HF2LI" 21 | 22 | hf2_example_zsync_poll: 23 | skip: true 24 | scenario_1: 25 | deviceparams: 26 | device_id: "HF2LI" 27 | -------------------------------------------------------------------------------- /hidden/python/check_zhinst_version.py: -------------------------------------------------------------------------------- 1 | import zhinst.core 2 | from packaging.version import parse 3 | 4 | from utils.python import cli_utils 5 | 6 | 7 | class InvalidVersionException(Exception): 8 | pass 9 | 10 | 11 | def expect_valid_zhinst_version(doc: str) -> None: 12 | # check version in docstring against version of installed zhinst 13 | assert isinstance(doc, str) 14 | doc_version = cli_utils.extract_version(doc) 15 | installed_version = parse(zhinst.core.__version__) 16 | 17 | if doc_version > installed_version: 18 | raise InvalidVersionException(f"version {doc_version} not satisfied") 19 | -------------------------------------------------------------------------------- /shfsg/python/Ramsey_command_table.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.zhinst.com/shfsg/commandtable/v1_0/schema#", 3 | "header": { 4 | "version": "1.0" 5 | }, 6 | "table": [ 7 | { 8 | "index": 0, 9 | "waveform": { 10 | "index": 0 11 | }, 12 | "amplitude00": { 13 | "value": 0.7 14 | }, 15 | "amplitude01": { 16 | "value": -0.7 17 | }, 18 | "amplitude10": { 19 | "value": 0.7 20 | }, 21 | "amplitude11": { 22 | "value": 0.7 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /hf2/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_connect: 11 | scenario_hf2: 12 | deviceparams: 13 | device_id: "HF2LI" 14 | 15 | example_pid_advisor_pll: 16 | scenario_hf2: 17 | deviceparams: 18 | device_id: "HF2LI" 19 | 20 | example_scope: 21 | scenario_hf2: 22 | deviceparams: 23 | device_id: "HF2LI" 24 | -------------------------------------------------------------------------------- /mf/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_autoranging_impedance: 11 | scenario_mfia: 12 | deviceparams: 13 | device_id: "MFIA" 14 | 15 | example_poll_impedance: 16 | scenario_mfia: 17 | deviceparams: 18 | device_id: "MFIA" 19 | 20 | example_impedance_module: 21 | scenario_mfia: 22 | deviceparams: 23 | device_id: "MFIA" -------------------------------------------------------------------------------- /uhf/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_awg_sourcefile: 11 | scenario_uhfli: 12 | deviceparams: 13 | device_id: "UHFLI/AWG" 14 | 15 | example_awg: 16 | scenario_uhfli: 17 | deviceparams: 18 | device_id: "UHFLI/AWG" 19 | 20 | example_boxcar: 21 | scenario_uhfli: 22 | deviceparams: 23 | device_id: "UHFLI/BOX" 24 | -------------------------------------------------------------------------------- /ghfli/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_poll: 11 | scenario_ghfli: 12 | deviceparams: 13 | device_id: "GHFLI" 14 | 15 | example_sweeper: 16 | scenario_ghfli: 17 | deviceparams: 18 | device_id: "GHFLI" 19 | 20 | example_triggered_data_acquisition: 21 | scenario_ghfli: 22 | deviceparams: 23 | device_id: "GHFLI" 24 | -------------------------------------------------------------------------------- /shfli/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_poll: 11 | scenario_shfli: 12 | deviceparams: 13 | device_id: "SHFLI" 14 | 15 | example_sweeper: 16 | scenario_shfli: 17 | deviceparams: 18 | device_id: "SHFLI" 19 | 20 | example_triggered_data_acquisition: 21 | scenario_shfli: 22 | deviceparams: 23 | device_id: "SHFLI" 24 | -------------------------------------------------------------------------------- /hidden/python/coverage_report_profiles.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains all profiles from batch LABONE_EXAMPLES_PYTHON 3 | # 4 | # When ever changing the batch, do not forget to manually update 5 | # this file and commit it again. 6 | # 7 | # Workflow see: https://wiki.zhinst.com/wiki/x/krmQCQ 8 | # 9 | profiles/jenkins/examples_python_hf2.json 10 | profiles/jenkins/examples_python_mfli_proxy.json 11 | profiles/jenkins/examples_python_mfia_remote.json 12 | profiles/jenkins/examples_python_uhf_1gbe_b.json 13 | profiles/jenkins/examples_python_uhfqa_1gbe.json 14 | profiles/jenkins/examples_python_pqsc.json 15 | profiles/jenkins/examples_python_hdawg8.json 16 | profiles/jenkins/examples_python_shfqa.json 17 | profiles/jenkins/examples_python_shfsg.json 18 | profiles/jenkins/examples_python_shfqc.json 19 | profiles/jenkins/examples_python_shfli.json 20 | profiles/jenkins/examples_python_ghfli.json 21 | -------------------------------------------------------------------------------- /uhfqa/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_delay: 11 | scenario_uhfqa: 12 | deviceparams: 13 | device_id: "UHFQA" 14 | 15 | example_monitor: 16 | scenario_uhfqa: 17 | deviceparams: 18 | device_id: "UHFQA" 19 | 20 | example_result: 21 | scenario_uhfqa: 22 | deviceparams: 23 | device_id: "UHFQA" 24 | 25 | example_threshold: 26 | scenario_uhfqa: 27 | deviceparams: 28 | device_id: "UHFQA" 29 | -------------------------------------------------------------------------------- /shfqc/python/README.adoc: -------------------------------------------------------------------------------- 1 | = SHFQC examples 2 | 3 | In addition to the examples in this directory the following examples from the 4 | SHFSG and SHFQA directory also apply to the SHFQC: 5 | 6 | == SHFSG 7 | * link:../../shfsg/python/example_cpmg.py[shfsg/python/example_cpmg.py] 8 | * link:../../shfsg/python/example_rabi.py[shfsg/python/example_rabi.py] 9 | * link:../../shfsg/python/example_ramsey.py[shfsg/python/example_ramsey.py] 10 | * link:../../shfsg/python/example_sine.py[shfsg/python/example_sine.py] 11 | 12 | == SHFQA 13 | * link:../../shfqa/python/example_resonator.py[shfsg/python/example_sine.py] 14 | * link:../../shfqa/python/example_qubit_readout_weights.py[shfsg/python/example_qubit_readout_weights.py] 15 | * link:../../shfqa/python/example_qubit_readout_measurement.py[shfsg/python/example_qubit_readout_measurement.py] 16 | * link:../../shfqa/python/example_qubit_readout_weights.py[shfsg/python/example_qubit_readout_weights.py] 17 | -------------------------------------------------------------------------------- /shfsg/python/Rabi.seq: -------------------------------------------------------------------------------- 1 | // Define constants in time domain 2 | const t_wid = 50e-9; 3 | const t_len = t_wid*8; 4 | const amp = 1; 5 | const n_amps = 101; 6 | const n_aves = 1000; 7 | const t_readout = 1e-6; 8 | 9 | // Convert to samples 10 | const s_rate = 2.0e9; 11 | const s_wid = t_wid*s_rate; 12 | const s_len= round(s_rate*t_len/16)*16; //Account for waveform granularity of 16 samples 13 | const s_readout = round(s_rate*t_readout/16)*16; 14 | 15 | // Define waveform and assign index 16 | wave w = gauss(s_len, amp, s_len/2, s_wid); 17 | assignWaveIndex(1,2,w,1,2,w,0); 18 | 19 | // Reset oscillator phases and trigger scope 20 | resetOscPhase(); 21 | setTrigger(1); 22 | setTrigger(0); 23 | 24 | //First Rabi amplitude and readout 25 | executeTableEntry(0); 26 | playZero(s_readout); 27 | 28 | //Increment Rabi amplitude each loop iteration 29 | repeat (n_amps-1) { 30 | resetOscPhase(); 31 | setTrigger(1); 32 | setTrigger(0); 33 | 34 | executeTableEntry(1); 35 | //Readout window 36 | playZero(s_readout); 37 | } 38 | -------------------------------------------------------------------------------- /shfsg/python/CPMG.seq: -------------------------------------------------------------------------------- 1 | // Define constants in time domain 2 | const t_wid = 50e-9; 3 | const t_len = t_wid*8; 4 | const amp = 1; 5 | const n_CPMG = 20; 6 | const t_evo = 50e-9; 7 | const t_readout = 1e-6; 8 | 9 | // Convert to samples 10 | const s_rate = 2.0e9; 11 | const s_wid = t_wid*s_rate; 12 | const s_len= round(s_rate*t_len/16)*16; //Account for waveform granularity of 16 samples 13 | const s_evo = round(s_rate*t_evo/16)*16; 14 | const s_readout = round(s_rate*t_readout/16)*16; 15 | 16 | // Define waveforms 17 | wave w = gauss(s_len, amp, s_len/2, s_wid); 18 | assignWaveIndex(1,2,w,1,2,w,0); 19 | 20 | // Reset oscillator phases and set trigger 21 | resetOscPhase(); 22 | setTrigger(1); 23 | setTrigger(0); 24 | 25 | //First pi/2 pulse 26 | executeTableEntry(0); 27 | 28 | //Main CPMG loop with n_CPMG pi pulses 29 | cvar i; 30 | for (i = 0; i < n_CPMG; i++) { 31 | playZero(s_evo); 32 | executeTableEntry(1); 33 | playZero(s_evo); 34 | } 35 | 36 | // Final pi/2 pulse 37 | executeTableEntry(0); 38 | 39 | //Readout window 40 | playZero(s_readout); 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Zurich Instruments AG 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enable normalization of line endings to LF. 2 | * text=auto 3 | 4 | # Declare files that will always have LF endings on checkout 5 | *.sh text eol=lf 6 | 7 | # Declare files that will always have CRLF line endings on checkout. 8 | *.bat text eol=crlf 9 | *.cmd text eol=crlf 10 | *.sln text eol=crlf 11 | *.vcxproj text eol=crlf 12 | *.vcxproj.filters text eol=crlf 13 | 14 | *.lib filter=lfs diff=lfs merge=lfs -text 15 | *.pdb filter=lfs diff=lfs merge=lfs -text 16 | *.dat filter=lfs diff=lfs merge=lfs -text 17 | *.deb filter=lfs diff=lfs merge=lfs -text 18 | *.rpm filter=lfs diff=lfs merge=lfs -text 19 | *.dll filter=lfs diff=lfs merge=lfs -text 20 | *.a filter=lfs diff=lfs merge=lfs -text 21 | *.so filter=lfs diff=lfs merge=lfs -text 22 | *.exe filter=lfs diff=lfs merge=lfs -text 23 | *.mat filter=lfs diff=lfs merge=lfs -text 24 | *.o filter=lfs diff=lfs merge=lfs -text 25 | *.doc filter=lfs diff=lfs merge=lfs -text 26 | *.pdf filter=lfs diff=lfs merge=lfs -text 27 | *.xls filter=lfs diff=lfs merge=lfs -text 28 | 29 | # Exclude minified files from 'git diff', 'git grep' etc. 30 | *.min.* -diff -text 31 | testing/ui/tools/chromedriver filter=lfs diff=lfs merge=lfs -text 32 | -------------------------------------------------------------------------------- /shfsg/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_sine: 11 | scenario_shfsg: 12 | deviceparams: 13 | device_id: "SHFSG4" 14 | scenario_shfqc: 15 | deviceparams: 16 | device_id: "SHFQC" 17 | 18 | example_cpmg: 19 | scenario_shfsg: 20 | deviceparams: 21 | device_id: "SHFSG4" 22 | scenario_shfqc: 23 | deviceparams: 24 | device_id: "SHFQC" 25 | 26 | example_rabi: 27 | scenario_shfsg: 28 | deviceparams: 29 | device_id: "SHFSG4" 30 | scenario_shfqc: 31 | deviceparams: 32 | device_id: "SHFQC" 33 | 34 | example_ramsey: 35 | scenario_shfsg: 36 | deviceparams: 37 | device_id: "SHFSG4" 38 | scenario_shfqc: 39 | deviceparams: 40 | device_id: "SHFQC" 41 | -------------------------------------------------------------------------------- /hdawg/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # For each example must be specified a dictionary entry with at least one test scenario. 2 | 3 | # Scenarios have the following entries: 4 | # * skip if true the scenario will be skipped (default = false) 5 | # * deviceparams defines which devices should be used for which variable (dev_type/option/option) 6 | # * params additional parameters for each testcase that differs from the default value 7 | 8 | # The test.spec.yml file looks like this: 9 | # 10 | # example_name1: 11 | # scenario_name1: 12 | # skip: false 13 | # deviceparams: 14 | # device_id_leader: 'HDAWG' 15 | # device_ids_follower: ['UHFLI/PID', 'MFLI/PID'] 16 | # ... 17 | # params: 18 | # testcase_name1: 19 | # amplitude: 0.1 20 | # plot: true 21 | # ... 22 | # ... 23 | # ... 24 | 25 | example_awg_commandtable: 26 | scenario_hdawg: 27 | deviceparams: 28 | device_id: "HDAWG8" 29 | 30 | example_awg_grouped_mode: 31 | scenario_hdawg: 32 | deviceparams: 33 | device_id: "HDAWG8" 34 | 35 | example_precompensation_curve_fit: 36 | scenario_hdawg: 37 | deviceparams: 38 | device_id: "HDAWG8" 39 | 40 | -------------------------------------------------------------------------------- /shfsg/python/Rabi_command_table.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.zhinst.com/shfsg/commandtable/v1_0/schema#", 3 | "header": { 4 | "version": "1.0" 5 | }, 6 | "table": [ 7 | { 8 | "index": 0, 9 | "waveform": { 10 | "index": 0 11 | }, 12 | "amplitude00": { 13 | "value": 0.0, 14 | "increment": false 15 | }, 16 | "amplitude01": { 17 | "value": -0.0, 18 | "increment": false 19 | }, 20 | "amplitude10": { 21 | "value": 0.0, 22 | "increment": false 23 | }, 24 | "amplitude11": { 25 | "value": 0.0, 26 | "increment": false 27 | } 28 | }, 29 | { 30 | "index": 1, 31 | "waveform": { 32 | "index": 0 33 | }, 34 | "amplitude00": { 35 | "value": 0.007, 36 | "increment": true 37 | }, 38 | "amplitude01": { 39 | "value": -0.007, 40 | "increment": true 41 | }, 42 | "amplitude10": { 43 | "value": 0.007, 44 | "increment": true 45 | }, 46 | "amplitude11": { 47 | "value": 0.007, 48 | "increment": true 49 | } 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /shfqa/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario. 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams defines which devices should be used for which variable. 7 | # The devices are defines by device_type(Option/Option) 8 | # * params parameter for each testcase that differ from the default value 9 | 10 | example_pulsed_resonator: 11 | scenario_shfqa: 12 | deviceparams: 13 | device_id: "SHFQA2" 14 | scenario_shfqc: 15 | deviceparams: 16 | device_id: "SHFQC" 17 | 18 | example_resonator: 19 | scenario_shfqa: 20 | deviceparams: 21 | device_id: "SHFQA2" 22 | scenario_shfqc: 23 | deviceparams: 24 | device_id: "SHFQC" 25 | 26 | example_qubit_readout_measurement: 27 | scenario_shfqa: 28 | deviceparams: 29 | device_id: "SHFQA2" 30 | scenario_shfqc: 31 | deviceparams: 32 | device_id: "SHFQC" 33 | 34 | example_qubit_readout_weights: 35 | scenario_shfqa: 36 | deviceparams: 37 | device_id: "SHFQA2" 38 | scenario_shfqc: 39 | deviceparams: 40 | device_id: "SHFQC" 41 | -------------------------------------------------------------------------------- /shfsg/python/CPMG_command_table.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.zhinst.com/shfsg/commandtable/v1_0/schema#", 3 | "header": { 4 | "version": "1.0" 5 | }, 6 | "table": [ 7 | { 8 | "index": 0, 9 | "waveform": { 10 | "index": 0 11 | }, 12 | "phase": { 13 | "value": 0.0 14 | }, 15 | "amplitude00": { 16 | "value": 0.3 17 | }, 18 | "amplitude01": { 19 | "value": -0.3 20 | }, 21 | "amplitude10": { 22 | "value": 0.3 23 | }, 24 | "amplitude11": { 25 | "value": 0.3 26 | } 27 | }, 28 | { 29 | "index": 1, 30 | "waveform": { 31 | "index": 0 32 | }, 33 | "phase": { 34 | "value": 90.0 35 | }, 36 | "amplitude00": { 37 | "value": 0.7 38 | }, 39 | "amplitude01": { 40 | "value": -0.7 41 | }, 42 | "amplitude10": { 43 | "value": 0.7 44 | }, 45 | "amplitude11": { 46 | "value": 0.7 47 | } 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /shfsg/python/Ramsey.seq: -------------------------------------------------------------------------------- 1 | // Define constants in time domain 2 | const amp = 1; //unitless scale factor 3 | const t_width = 50e-9; //FWHM of 50ns 4 | const t_length = 8*t_width; //temporal length in terms of FWHM 5 | const t_step = 100e-9; //step size of 100ns 6 | const n_evo = 50; //number of time steps 7 | const n_aves = 1000; //number of averages 8 | const t_readout = 1e-6; //readout time 9 | 10 | // Constants converted to samples 11 | const s_rate = 2.0e9; //sampling rate being used 12 | const s_length = round(s_rate*t_length/16)*16; //account for waveform granularity of 16 samples 13 | const s_width = s_rate*t_width; 14 | const s_readout = round(s_rate*t_readout/16)*16; 15 | const s_step = round(s_rate*t_step/16)*16; 16 | 17 | // Generate gaussian waveform 18 | wave w = gauss(s_length,amp,s_length/2,s_width); 19 | assignWaveIndex(1,2,w,1,2,w,0); 20 | 21 | //Repeat Ramsey loop n_aves times 22 | repeat (n_aves) { 23 | // Reset modulation phase and set trigger 24 | resetOscPhase(); 25 | setTrigger(1); 26 | setTrigger(0); 27 | 28 | //Ramsey loop 29 | var i; 30 | for (i = 0; i < n_evo; i += 1) { 31 | // Play pi/2 pulse followed by evolution time and second pi/2 pulse, then readout 32 | executeTableEntry(0); 33 | playZero(32+i*s_step); 34 | executeTableEntry(0); 35 | playZero(s_readout); 36 | } 37 | playZero(s_readout); 38 | } 39 | -------------------------------------------------------------------------------- /ziAddExamplePath.m: -------------------------------------------------------------------------------- 1 | function ziAddExamplePath 2 | % ZIADDEXAMPLEPATH add the LabOne Matlab examples to Matlab's Search Path 3 | % 4 | % USAGE: 5 | % ziAddExamplePath(); 6 | 7 | % Get the name of the current function complete with full path 8 | mfile = which(mfilename); 9 | [pathstr, name] = fileparts(mfile); 10 | dirs = {'hf2-mf-uhf' 'hdawg' 'hf2' 'mf' 'uhf' 'shfli' 'ghfli'}; 11 | for dir = dirs 12 | driverPath = [pathstr filesep string(dir) filesep 'matlab']; 13 | addpath(char(strjoin(driverPath,''))) 14 | end 15 | dbs = dbstack; 16 | % If ziAddExamplePath was called directly in Matlab output some help, otherwise output nothing. 17 | if strcmp(dbs(end).name, 'ziAddExamplePath') 18 | fprintf('Added ziDAQ''s Examples directories to Matlab''s path\n') 19 | fprintf('for this session.\n\n'); 20 | fprintf('To make this configuration persistent across Matlab sessions either:\n\n') 21 | fprintf('1. Run the ''pathtool'' command in the Matlab Command Window and add the\n') 22 | fprintf(' following paths WITH SUBFOLDERS to the Matlab search path:\n\n') 23 | fprintf(' %s\n', pathstr); 24 | fprintf('\nor\n\n'); 25 | fprintf('2. Add the following line to your Matlab startup.m file:\n'); 26 | fprintf('\n'); 27 | fprintf(' run(''%s%s%s'');\n\n', pathstr, filesep, name); 28 | fprintf('\n'); 29 | fprintf('See the LabOne Programming Manual for more help.\n'); 30 | end 31 | -------------------------------------------------------------------------------- /hidden/python/runner_examples.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | 3 | from hidden.python.lib_testspec import ExampleSource, Testcontext, TestcontextDevice 4 | from hidden.python.coverage_report import CoverageReport 5 | 6 | DIRECTORY_OF_THIS_FILE = pathlib.Path(__file__).absolute().parent 7 | 8 | REPORT_FILENAME = "runner_examples_coverage_report.html" 9 | 10 | if __name__ == "__main__": 11 | print("Unique scenario names") 12 | for scenario_name in ExampleSource.testscenario_names(): 13 | print(f" {scenario_name}") 14 | 15 | # This list corresponds to a list of calls to zipytest using different profiles 16 | report = CoverageReport(testscenarios=ExampleSource.testscenario_names()) 17 | 18 | for testcontext in ( 19 | Testcontext( 20 | profile_name="profile3", 21 | devices=[ 22 | TestcontextDevice( 23 | dev_id="dev2109", dev_type="UHFQA", options=["PID", "A", "C"] 24 | ), 25 | ], 26 | ), 27 | ): 28 | print(f"Testcontext: {testcontext.profile_name}") 29 | report.increment_by_testcontext(testcontext=testcontext) 30 | 31 | for example in ExampleSource.iter_examples(): 32 | print(f"- Testing {example.filename_relative}") 33 | for testcase in example.iter_testcases(testcontext): 34 | print(testcase.params_text) 35 | print(" ** TESTING " + testcase.func_text) 36 | try: 37 | testcase.run() 38 | print(f" TEST PASSED") 39 | except Exception as e: 40 | print(f" TEST FAILED: {repr(e)}") 41 | 42 | print(f"Write '{REPORT_FILENAME}'") 43 | report.write_html(filename=DIRECTORY_OF_THIS_FILE / REPORT_FILENAME) 44 | -------------------------------------------------------------------------------- /hidden/.vscode/launch.json.template: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 4 | "version": "0.2.0", 5 | "configurations": [ 6 | { 7 | "name": "run current example", 8 | "type": "python", 9 | "request": "launch", 10 | "program": "${file}", 11 | "args": [ 12 | "${input:pickDevice}" 13 | ], 14 | "console": "integratedTerminal" 15 | }, 16 | { 17 | "name": "runner_examples.py", 18 | "type": "python", 19 | "request": "launch", 20 | "module": "hidden.python.runner_examples", 21 | "console": "integratedTerminal" 22 | }, 23 | { 24 | "name": "consistency_check_cli.py", 25 | "type": "python", 26 | "request": "launch", 27 | "module": "hidden.python.consistency_check_cli", 28 | "console": "integratedTerminal" 29 | }, 30 | { 31 | "name": "consistency_check_testspec.py", 32 | "type": "python", 33 | "request": "launch", 34 | "module": "hidden.python.consistency_check_testspec", 35 | "console": "integratedTerminal" 36 | }, 37 | { 38 | "name": "pylint", 39 | "type": "python", 40 | "request": "launch", 41 | "module": "pylint", 42 | "cwd": "${workspaceFolder}", 43 | "args": [ 44 | "--ignore-paths", "hidden/,utils/python/docopt.py", 45 | "**/*.py" 46 | ], 47 | "console": "integratedTerminal" 48 | }, 49 | ], 50 | "inputs": [ 51 | { 52 | "id": "pickDevice", 53 | "type": "promptString", 54 | "description": "Select the device to run the example on " 55 | } 56 | ] 57 | } -------------------------------------------------------------------------------- /shfqa/python/helper_commons.py: -------------------------------------------------------------------------------- 1 | """ Common helper functions used by the SHFQA examples 2 | """ 3 | 4 | # Copyright 2021 Zurich Instruments AG 5 | import numpy as np 6 | 7 | 8 | def generate_flat_top_gaussian( 9 | frequencies, pulse_duration, rise_fall_time, sampling_rate, scaling=0.9 10 | ): 11 | """Returns complex flat top Gaussian waveforms modulated with the given frequencies. 12 | 13 | Arguments: 14 | 15 | frequencies (array): array specifying the modulation frequencies applied to each 16 | output wave Gaussian 17 | 18 | pulse_duration (float): total duration of each Gaussian in seconds 19 | 20 | rise_fall_time (float): rise-fall time of each Gaussian edge in seconds 21 | 22 | sampling_rate (float): sampling rate in samples per second based on which to 23 | generate the waveforms 24 | 25 | scaling (optional float): scaling factor applied to the generated waveforms (<=1); 26 | use a scaling factor <= 0.9 to avoid overshoots 27 | 28 | Returns: 29 | 30 | pulses (dict): dictionary containing the flat top Gaussians as values 31 | 32 | """ 33 | if scaling > 1: 34 | raise ValueError( 35 | "The scaling factor has to be <= 1 to ensure the generated waveforms lie within the \ 36 | unit circle." 37 | ) 38 | 39 | from scipy.signal.windows import gaussian 40 | 41 | rise_fall_len = int(rise_fall_time * sampling_rate) 42 | pulse_len = int(pulse_duration * sampling_rate) 43 | 44 | std_dev = rise_fall_len // 10 45 | 46 | gauss = gaussian(2 * rise_fall_len, std_dev) 47 | flat_top_gaussian = np.ones(pulse_len) 48 | flat_top_gaussian[0:rise_fall_len] = gauss[0:rise_fall_len] 49 | flat_top_gaussian[-rise_fall_len:] = gauss[-rise_fall_len:] 50 | 51 | flat_top_gaussian *= scaling 52 | 53 | pulses = {} 54 | time_vec = np.linspace(0, pulse_duration, pulse_len) 55 | 56 | for i, f in enumerate(frequencies): 57 | pulses[i] = flat_top_gaussian * np.exp(2j * np.pi * f * time_vec) 58 | 59 | return pulses 60 | -------------------------------------------------------------------------------- /hidden/python/consistency_check_testspec.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import yaml 3 | 4 | from hidden.python.lib_testspec import ( 5 | TESTSPEC_DEVICEPARAMS, 6 | FILENAME_TESTSPEC, 7 | TESTSPEC_SKIP, 8 | ) 9 | 10 | DIRECTORY_API_EXAMPLES = Path(".").absolute() 11 | assert (DIRECTORY_API_EXAMPLES / "hidden" / "python").exists() 12 | 13 | 14 | def consistency_check_test_example(yml_content: dict, example: str): 15 | """ 16 | Lint the test specifications for a single example 17 | """ 18 | if not example in yml_content: 19 | return False, f"missing entry in local {FILENAME_TESTSPEC}." 20 | 21 | testspec = yml_content[example] 22 | if not testspec: 23 | message = f"at least one scenario must be specified in the {FILENAME_TESTSPEC} for \ 24 | '{example}'." 25 | return False, message 26 | 27 | for scenario_name, scenario in testspec.items(): 28 | if TESTSPEC_SKIP in scenario: 29 | return True, "" 30 | if TESTSPEC_DEVICEPARAMS in scenario: 31 | return True, "" 32 | message = f"either {TESTSPEC_DEVICEPARAMS} or {TESTSPEC_SKIP} must be defined in the \ 33 | {FILENAME_TESTSPEC}, but none of them was found for '{scenario_name}' in '{example}'." 34 | return False, message 35 | 36 | 37 | def consistency_check_testspecs(): 38 | """ 39 | Lint the test specifications. 40 | """ 41 | print("Check test spec of python examples:") 42 | error = False 43 | for example_file in DIRECTORY_API_EXAMPLES.glob("**/example*.py"): 44 | yaml_file = example_file.parent / FILENAME_TESTSPEC 45 | with yaml_file.open("r") as stream: 46 | yml_content = yaml.safe_load(stream) 47 | result, message = consistency_check_test_example(yml_content, example_file.stem) 48 | if result: 49 | print(f"[✓] {example_file}") 50 | else: 51 | print(f"[x] {example_file}") 52 | print(f" {message}") 53 | error = True 54 | return not error 55 | 56 | 57 | if __name__ == "__main__": 58 | if not consistency_check_testspecs(): 59 | raise Exception("Test failed") 60 | -------------------------------------------------------------------------------- /hidden/python/coverage_report.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | 3 | from hidden.python.lib_testspec import ExampleSource, Testcontext 4 | from hidden.python import coverage_report_html 5 | 6 | 7 | class CoverageReport: 8 | def __init__(self, testscenarios: list): 9 | assert isinstance(testscenarios, list) 10 | self._testscenarios = testscenarios 11 | self._profiles = set() 12 | self._cell = {} 13 | self.errors = [] 14 | self.passed = False 15 | 16 | def increment(self, testscenario: str, profile: str): 17 | key = (testscenario, profile) 18 | self._cell[key] = self._cell.get(key, 0) + 1 19 | 20 | def increment_by_testcontext(self, testcontext: Testcontext): 21 | assert isinstance(testcontext, Testcontext) 22 | profile = testcontext.profile_name 23 | self._profiles.add(profile) 24 | for example in ExampleSource.iter_examples(): 25 | for scenario in example.iter_testscenarios(testcontext=testcontext): 26 | self.increment(testscenario=scenario.name_full, profile=profile) 27 | 28 | def write_html(self, filename: pathlib.Path): 29 | passed = True 30 | with coverage_report_html.Html(filename=filename) as html: 31 | html.add_html("

python api examples coverage report

\n") 32 | 33 | for error in self.errors: 34 | html.add_html(f"

{error}

") 35 | 36 | sorted_profiles = sorted(self._profiles) 37 | profile_coverage = {} 38 | 39 | with html.table as table: 40 | profiles_with_linebreaks = [ 41 | profile.replace("/", "/
") for profile in sorted_profiles 42 | ] 43 | table.add_header( 44 | [ 45 | "testscenario", 46 | "coverage", 47 | ] 48 | + profiles_with_linebreaks 49 | ) 50 | for testscenario in self._testscenarios: 51 | cells = [ 52 | testscenario, 53 | ] 54 | coverage_total = 0 55 | for profile in sorted_profiles: 56 | key = (testscenario, profile) 57 | coverage = self._cell.get(key, 0) 58 | coverage_total += coverage 59 | profile_coverage[profile] = ( 60 | profile_coverage.get(profile, 0) + coverage 61 | ) 62 | cells.append(str(coverage)) 63 | 64 | cells.insert(1, str(coverage_total)) 65 | table.add_row(cells) 66 | if coverage_total == 0: 67 | passed = False 68 | 69 | for profile, coverage in profile_coverage.items(): 70 | if coverage == 0: 71 | html.add_html(f"

Never used: {profile}

") 72 | 73 | self.passed = passed 74 | -------------------------------------------------------------------------------- /shfqa/python/example_resonator.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupyter: 3 | jupytext: 4 | text_representation: 5 | extension: ipynb,md 6 | format_name: markdown 7 | format_version: '1.3' 8 | jupytext_version: 1.14.1 9 | kernelspec: 10 | display_name: Python 3 (ipykernel) 11 | language: python 12 | name: python3 13 | --- 14 | 15 | # Zurich Instruments LabOne Python API Example 16 | 17 | 18 | ## Run a frequency sweep with a SHFQA 19 | 20 | 21 | Run a frequency sweep with a SHFQA. 22 | 23 | Requirements: 24 | * LabOne Version >= 21.08 25 | * Instruments: 26 | 1 x SHFQA or SHFQC Instrument 27 | * Signal output 0 connected to signal input 0 with a BNC cable 28 | 29 | ----- 30 | 31 | ```python 32 | import zhinst.core 33 | from zhinst.utils.shf_sweeper import ( 34 | ShfSweeper, 35 | AvgConfig, 36 | RfConfig, 37 | SweepConfig, 38 | ) 39 | ``` 40 | 41 | ### 1. Connect the device 42 | 43 | 44 | Set up the connection with the device. Firstly create an API session with a Data Server. Then the Data Server connects to the device. 45 | 46 | ```python 47 | device_id = "dev2345" # Device serial number available on its rear panel. 48 | interface = "1GbE" # For Ethernet connection 49 | #interface = "USB" # For USB connection 50 | 51 | server_host = "localhost" 52 | server_port = 8004 53 | api_level = 6 # Maximum API level supported for all instruments. 54 | 55 | # Create an API session to the Data Server. 56 | daq = zhinst.core.ziDAQServer(server_host, server_port, api_level) 57 | 58 | # Establish a connection between Data Server and Device. 59 | daq.connectDevice(device_id, interface) 60 | ``` 61 | 62 | ### 2. Create a Sweeper and configure it 63 | 64 | 65 | Instantiate the sweeper. 66 | 67 | ```python 68 | sweeper = ShfSweeper(daq, device_id) 69 | ``` 70 | 71 | Configure the sweeper. 72 | 73 | ```python 74 | # Frequency range settings for the sweep 75 | sweep_config = SweepConfig( 76 | start_freq=-200e6, 77 | stop_freq=300e6, 78 | num_points=51, 79 | mapping="linear", 80 | oscillator_gain=0.8, 81 | ) 82 | 83 | # Averaging settings for the sweep 84 | avg_config = AvgConfig(integration_time=100e-6, num_averages=2, mode="sequential") 85 | 86 | # RF input and output settings for the sweep 87 | rf_config = RfConfig(channel=0, input_range=0, output_range=0, center_freq=4e9) 88 | 89 | 90 | sweeper.configure(sweep_config, avg_config, rf_config) 91 | 92 | ``` 93 | 94 | ### 3. Run the measurement and plot the data 95 | 96 | 97 | Turn on the input and output for the channel. 98 | 99 | ```python 100 | daq.set( 101 | [ 102 | (f"/{device_id}/qachannels/{rf_config.channel}/input/on", 1), 103 | (f"/{device_id}/qachannels/{rf_config.channel}/output/on", 1), 104 | ] 105 | ) 106 | ``` 107 | 108 | Start a sweep. 109 | 110 | ```python 111 | sweeper.run() 112 | ``` 113 | 114 | Get the result after the sweep. 115 | 116 | ```python 117 | result = sweeper.get_result() 118 | num_points_result = len(result["vector"]) 119 | print(f"Measured at {num_points_result} frequency points.") 120 | ``` 121 | 122 | Plot the the result over the frequency. 123 | 124 | ```python 125 | sweeper.plot() 126 | ``` 127 | -------------------------------------------------------------------------------- /hf2/python/example_connect.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupyter: 3 | jupytext: 4 | formats: ipynb,md 5 | text_representation: 6 | extension: .md 7 | format_name: markdown 8 | format_version: '1.3' 9 | jupytext_version: 1.13.7 10 | kernelspec: 11 | display_name: Python 12 | language: python 13 | name: python3 14 | --- 15 | 16 | # Zurich Instruments LabOne Python API Example 17 | # Connect to a Zurich Instruments HF2 device 18 | 19 | Demonstrate how to connect to a Zurich Instruments HF2 device via the Data Server 20 | program. 21 | Create an API session by connecting to a Zurich Instruments 22 | device via the Data Server, ensure the demodulators are enabled and obtain a 23 | single demodulator sample via getSample(). Calculate the sample's RMS 24 | amplitude and add it as a field to the "sample" dictionary. 25 | 26 | > Note: 27 | > 28 | > This is intended to be a simple example demonstrating how to connect to a 29 | > Zurich Instruments device from Python. In most cases, data acquisition 30 | > should use either ziDAQServer's poll() method or an instance of the 31 | > ziDAQRecorder class, not the getSample() method. 32 | 33 | Requirements: 34 | * LabOne Version >= 20.02 35 | * Instruments: 36 | 1 x Zurich Instruments HF2 device 37 | 38 | --- 39 | 40 | ```python 41 | import numpy as np 42 | import zhinst.core 43 | ``` 44 | 45 | Set up the connection. The connection is always through a session to a 46 | Data Server. The Data Server then connects to the device. 47 | 48 | The LabOne Data Server needs to run within the network, either on localhost when 49 | starting LabOne on your local computer or a remote server. (The MFLI/IA devices 50 | have a Data Server running on the device itself, please see the 51 | [user manual](https://docs.zhinst.com/mfli_user_manual/getting_started/device_connectivity_instrument.html) 52 | for detailed explanation.) 53 | 54 | ```python 55 | device_id = "dev1234" # Device serial number available on its rear panel. 56 | interface = "USB" 57 | 58 | server_host = "localhost" 59 | server_port = 8005 60 | api_level = 1 61 | 62 | # Create an API session to the Data Server. 63 | daq = zhinst.core.ziDAQServer(server_host, server_port, api_level) 64 | # Establish a connection between Data Server and Device. 65 | daq.connectDevice(device_id, interface) 66 | ``` 67 | 68 | Enable the demodulator and set the demodulator output rate. 69 | 70 | ```python 71 | settings = [ 72 | (f"/{device_id}/demods/0/enable", 1), 73 | (f"/{device_id}/demods/0/rate", 1.0e3) 74 | ] 75 | daq.set(settings) 76 | ``` 77 | 78 | Obtain one demodulator sample. If the demodulator is not enabled (as 79 | above) then the command will time out: we'll get a RuntimeError showing 80 | that a `ZIAPITimeoutException` occurred. 81 | 82 | ```python 83 | sample = daq.getSample(f"/{device_id}/demods/0/sample") 84 | ``` 85 | 86 | Extract the in-phase and quadrature components of demodulated signal. 87 | 88 | ```python 89 | X = sample['x'][0] 90 | Y = sample['y'][0] 91 | print(f"Measured in-phase component:\t {X:.3e} V") 92 | print(f"Measured quadrature component:\t {Y:.3e} V") 93 | ``` 94 | 95 | Calculate the RMS amplitude and phase of demodulated signal.. 96 | 97 | ```python 98 | R = np.abs(X + 1j*Y) 99 | Theta = np.arctan2(Y,X) 100 | print(f"Measured RMS amplitude:\t {R:.3e} V") 101 | print(f"Measured signal phase:\t {(180/np.pi)*Theta:.2f} deg") 102 | ``` 103 | -------------------------------------------------------------------------------- /hf2-mf-uhf/python/example_connect.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupyter: 3 | jupytext: 4 | formats: ipynb,md 5 | text_representation: 6 | extension: .md 7 | format_name: markdown 8 | format_version: '1.3' 9 | jupytext_version: 1.13.7 10 | kernelspec: 11 | display_name: Python 12 | language: python 13 | name: python3 14 | --- 15 | 16 | # Zurich Instruments LabOne Python API Example 17 | # Connect to a Zurich Instruments device 18 | 19 | Demonstrate how to connect to a Zurich Instruments device via the Data Server 20 | program. Create an API session by connecting to a Zurich Instruments device via 21 | the Data Server. 22 | 23 | Identify the device and check consistency across the LabOne stack. 24 | 25 | > Note: 26 | > 27 | > This example works with all Zurich Instruments devices except the HF2LI. A 28 | > separate example `example_connect` in the hf2 directory exists for the HF2LI. 29 | 30 | Requirements: 31 | * LabOne Version >= 20.02 32 | * Instruments: 33 | 1 x Zurich Instruments device 34 | 35 | --- 36 | 37 | ```python 38 | import zhinst.core 39 | ``` 40 | 41 | Set up the connection. The connection is always through a session to a 42 | Data Server. The Data Server then connects to the device. 43 | 44 | The LabOne Data Server needs to run within the network, either on localhost when 45 | starting LabOne on your local computer or a remote server. (The MFLI/IA devices 46 | have a Data Server running on the device itself, please see the 47 | [user manual](https://docs.zhinst.com/mfli_user_manual/getting_started/device_connectivity_instrument.html) 48 | for detailed explanation.) 49 | 50 | ```python 51 | device_id = "dev2345" # Device serial number available on its rear panel. 52 | interface = "1GbE" # For Ethernet connection or when MFLI/MFIA is connected to a remote Data Server. 53 | #interface = "USB" # For all instruments connected to the host computer via USB except MFLI/MFIA. 54 | #interface = "PCIe" # For MFLI/MFIA devices in case the Data Server runs on the device. 55 | 56 | server_host = "localhost" 57 | server_port = 8004 58 | api_level = 6 # Maximum API level supported for all instruments. 59 | 60 | # Create an API session to the Data Server. 61 | daq = zhinst.core.ziDAQServer(server_host, server_port, api_level) 62 | # Establish a connection between Data Server and Device. 63 | daq.connectDevice(device_id, interface) 64 | ``` 65 | 66 | Identify the connected device by trigger a blinking of the power led for a few seconds. 67 | 68 | ```python 69 | daq.setInt(f"/{device_id}/system/identify", 1) 70 | ``` 71 | 72 | The firmware revision should match the LabOne version to ensure deterministic behavior. 73 | 74 | ```python 75 | import json 76 | status_flag = json.loads(daq.getString("/zi/devices"))[device_id.upper()]["STATUSFLAGS"] 77 | if status_flag & 1 << 8: 78 | print( 79 | "The device is currently updating please try again after the update " 80 | "process is complete" 81 | ) 82 | elif status_flag & 1 << 4 or status_flag & 1 << 5: 83 | print( 84 | "The firmware does not match the LabOne version. " 85 | "Please update the firmware, e.g. in the LabOne UI." 86 | ) 87 | elif status_flag & 1 << 6 or status_flag & 1 << 7: 88 | print( 89 | "The firmware does not match the LabOne version. " 90 | "Please update LabOne to the latest version from " 91 | "https://www.zhinst.com/support/download-center." 92 | ) 93 | else: 94 | print("The Firmware matches the LabOne version") 95 | ``` 96 | -------------------------------------------------------------------------------- /hidden/python/consistency_check_cli.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import importlib 3 | import importlib.util 4 | import inspect 5 | 6 | from utils.python.cli_utils import extract_devices 7 | from utils.python.cli_utils import extract_version 8 | from utils.python.docopt import parse_defaults 9 | from utils.python.docopt import parse_section 10 | from .add_example_path import add_example_path 11 | 12 | DIRECTORY_API_EXAMPLES = Path(".").absolute() 13 | assert (DIRECTORY_API_EXAMPLES / "hidden" / "python").exists() 14 | 15 | 16 | def check_arguments(module): 17 | """ 18 | Checks if all arguments are documented for the cli 19 | """ 20 | options = parse_defaults(module.__doc__) 21 | kwarg = [] 22 | for option in options: 23 | kwarg.append(option.long.strip("-")) 24 | function_param = inspect.signature(module.run_example).parameters 25 | missing_args = [] 26 | for param in function_param: 27 | if ( 28 | not (param in kwarg or ("no-" + param) in kwarg) 29 | and not f"<{param}>" in module.__doc__ 30 | ): 31 | missing_args.append(param) 32 | return missing_args 33 | 34 | 35 | class DocstringException(Exception): 36 | pass 37 | 38 | 39 | def check_docstring(example_file: Path): 40 | """ 41 | Checks if the docstring of the example matches the requirements 42 | """ 43 | spec = importlib.util.spec_from_file_location(example_file.stem, example_file) 44 | assert spec is not None 45 | module = importlib.util.module_from_spec(spec) 46 | spec.loader.exec_module(module) 47 | 48 | # check for docstring 49 | if not module.__doc__: 50 | raise DocstringException("missing docstring.") 51 | 52 | # check Usage 53 | usage_sections = parse_section("usage:", module.__doc__) 54 | if len(usage_sections) == 0: 55 | raise DocstringException("missing usage: in docstring.") 56 | if len(usage_sections) > 1: 57 | raise DocstringException("more than one usage: in docstring.") 58 | 59 | # check arguments 60 | missing_args = check_arguments(module) 61 | if len(missing_args) > 0: 62 | raise DocstringException( 63 | f"arguments {missing_args} not documented in docstring" 64 | ) 65 | 66 | # check Devices 67 | if len(extract_devices(module.__doc__)) == 0: 68 | raise DocstringException( 69 | "missing variable with a specified device type in docstring." 70 | ) 71 | 72 | # check Version 73 | try: 74 | extract_version(module.__doc__) 75 | except Exception as e: 76 | raise DocstringException("missing minimal LabOne version in docstring.") from e 77 | 78 | 79 | def check_examples(): 80 | """ 81 | Checks if every requirement for the command line tool is satisfied. 82 | """ 83 | print("Check cli of python examples") 84 | error = False 85 | for example_file in DIRECTORY_API_EXAMPLES.glob("**/example*.py"): 86 | try: 87 | with add_example_path(example_file): 88 | check_docstring(example_file) 89 | print(f"[✓] {example_file}") 90 | except DocstringException as e: 91 | print(f"[x] {example_file}") 92 | print(f" {e}") 93 | error = True 94 | return not error 95 | 96 | 97 | if __name__ == "__main__": 98 | if not check_examples(): 99 | raise Exception("Test failed") 100 | -------------------------------------------------------------------------------- /hf2-mf-uhf/matlab/example_connect.m: -------------------------------------------------------------------------------- 1 | function r = example_connect(device_id) 2 | % EXAMPLE_CONNECT A simple example demonstrating how to connect to a Zurich Instruments device 3 | % 4 | % USAGE R = EXAMPLE_CONNECT(DEVICE_ID) 5 | % 6 | % Connect to the Zurich Instruments device specified by DEVICE_ID, obtain a 7 | % single demodulator sample and calculate its RMS amplitude R. DEVICE_ID 8 | % should be a string, e.g., 'dev1000' or 'uhf-dev1000'. 9 | % 10 | % NOTE This is intended to be a simple example demonstrating how to connect 11 | % to a Zurich Instruments device from ziPython. In most cases, data acquistion 12 | % should use either ziDAQServer's poll() method or an instance of the 13 | % ziDAQRecorder class. 14 | % 15 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 16 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 17 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 18 | % subfolders and run the Matlab function ziAddPath(). 19 | % >>> ziAddPath; 20 | % 21 | % Use either of the commands: 22 | % >>> help ziDAQ 23 | % >>> doc ziDAQ 24 | % in the Matlab command window to obtain help on all available ziDAQ commands. 25 | % 26 | % See also EXAMPLE_CONNECT_CONFIG, EXAMPLE_POLL. 27 | % 28 | % Copyright 2008-2018 Zurich Instruments AG 29 | 30 | clear ziDAQ; 31 | 32 | if ~exist('device_id', 'var') 33 | error(['No value for device_id specified. The first argument to the ' ... 34 | 'example should be the device ID on which to run the example, ' ... 35 | 'e.g. ''dev1000'' or ''uhf-dev1000''.']) 36 | end 37 | 38 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 39 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 40 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 41 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 42 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 43 | fprintf('On Windows this is typically:\n'); 44 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 45 | return 46 | end 47 | 48 | % The API level supported by this example. 49 | supported_apilevel = 6; 50 | % Create an API session; connect to the correct Data Server for the device. 51 | [device, ~] = ziCreateAPISession(device_id, supported_apilevel); 52 | 53 | branches = ziDAQ('listNodes', ['/' device ], 0); 54 | % Only configure if we have lock-in functionality available. 55 | if any(strcmpi([branches], 'DEMODS')) 56 | % Enable the demodulator and set a reasonable rate, otherwise the getSample 57 | % command below will timeout as it won't receive any demodulator data. 58 | ziDAQ('setInt', ['/' device '/demods/0/enable'], 1); 59 | ziDAQ('setDouble', ['/' device '/demods/0/rate'], 1.0e3); 60 | 61 | % Perform a global synchronisation between the device and the data server: 62 | % Ensure that the settings have taken effect on the device before issuing the 63 | % `getSample` command. Note: `sync` must be issued after waiting for the 64 | % demodulator filter to settle above. 65 | ziDAQ('sync'); 66 | 67 | % Get a single demodulator sample. Note, `poll` or other higher-level 68 | % functionality should almost always be be used instead of `getSample`. 69 | sample = ziDAQ('getSample', ['/' device '/demods/0/sample']); 70 | r = abs(sample.x + j*sample.y); 71 | fprintf('Measured RMS amplitude: %eV.\n', r); 72 | else 73 | r = nan; 74 | end 75 | 76 | end 77 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: [test, deploy, mirror] 2 | 3 | default: 4 | tags: 5 | - linux 6 | - docker 7 | 8 | .get-latest-zhinst-whl: &get-latest-zhinst-whl 9 | before_script: 10 | - LATEST_HREF=$(wget -q -O - https://artifactory.zhinst.com/artifactory/labone/master/ | grep -o 'href="[^"]*"' | sed 's/href="\([^"]*\)"/\1/' | tail -n 1) 11 | - wget -r -l 1 --no-parent -A 'zhinst_core*cp39-cp39-manylinux1_x86_64.whl' https://artifactory.zhinst.com/artifactory/labone/master/${LATEST_HREF} 12 | - pip install artifactory.zhinst.com/artifactory/labone/master/*/*cp39-cp39-manylinux1_x86_64.whl 13 | - rm -r artifactory.zhinst.com 14 | 15 | format-black: 16 | stage: test 17 | image: python:3.9 18 | script: 19 | - python3 -m pip install -r requirements-dev.txt 20 | - python3 -m black --force-exclude utils/python/docopt.py --check --diff . 21 | rules: 22 | - if: $CI_COMMIT_REF_PROTECTED == "true" 23 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 24 | 25 | test-cli: 26 | <<: *get-latest-zhinst-whl 27 | stage: test 28 | image: python:3.9 29 | script: 30 | - pip3 install -r requirements.txt 31 | - python3 -m hidden.python.consistency_check_cli 32 | rules: 33 | - if: $CI_COMMIT_REF_PROTECTED == "true" 34 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 35 | 36 | test-test.spec: 37 | stage: test 38 | image: python:3.9 39 | script: 40 | - pip3 install pyyaml zhinst jupytext 41 | - python3 -m hidden.python.consistency_check_testspec 42 | rules: 43 | - if: $CI_COMMIT_REF_PROTECTED == "true" 44 | - if: $CI_PIPELINE_SOURCE == "merge_request_event" 45 | 46 | public-github: 47 | stage: mirror 48 | image: roemer/git-filter-repo 49 | script: 50 | - pip3 install jupytext 51 | - git clone --mirror https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.zhinst.com/labone/api-examples.git 52 | - cd api-examples.git 53 | # Cleanup repo 54 | - echo "${HIDDEN_RELEASES}" >> hidden.tmp 55 | - git branch --format='%(refname:short)' | grep -f hidden.tmp | xargs git branch -D || true 56 | - rm hidden.tmp 57 | - git branch --format='%(refname:short)' | grep -v "release-" | xargs git branch -D 58 | - grep "heads" packed-refs > packed-refs.temp 59 | - mv packed-refs.temp packed-refs 60 | - git filter-repo --force --path-glob '**/test.spec.yml' --path-glob 'hidden/**/*' --path-glob 'hidden/*' --path '.gitlab-ci.yml' --path '.gitlab-ci.yml' --path '.pylintrc' --path '.jupytext' --invert-path 61 | # Convert markdown to jupyter notebook 62 | - | 63 | git filter-repo --blob-callback ' 64 | if b"jupytext:" in blob.data: 65 | import jupytext 66 | try: 67 | ntbk = jupytext.reads(blob.data.decode()) 68 | blob.data = jupytext.writes(ntbk, fmt="ipynb").encode("utf-8") 69 | except Exception as e: 70 | print(e) 71 | ' 72 | - | 73 | git filter-repo --filename-callback ' 74 | if b".md" in filename and b"example" in filename: 75 | return filename.replace(b".md", b".ipynb") 76 | return filename 77 | ' 78 | # Deploy to github 79 | - eval $(ssh-agent -s) 80 | - echo -e "-----BEGIN OPENSSH PRIVATE KEY-----\n${SSH_PRIVATE_KEY}\n-----END OPENSSH PRIVATE KEY-----" | ssh-add - 81 | - mkdir -p ~/.ssh && chmod 700 ~/.ssh 82 | - ssh-keyscan github.com >> ~/.ssh/known_hosts 83 | - chmod 644 ~/.ssh/known_hosts 84 | - git config --global user.email "gitlab-ci@zhinst.com" 85 | - git config --global user.name "GitLab CI" 86 | - git push --mirror git@github.com:zhinst/labone-api-examples.git 87 | rules: 88 | - if: '$CI_COMMIT_REF_NAME =~ /release-.*/' 89 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image:https://img.shields.io/badge/code%20style-black-000000.svg[link="https://github.com/psf/black"] 4 | image:https://img.shields.io/badge/License-MIT-yellow.svg[link="https://opensource.org/licenses/MIT"] 5 | image:https://img.shields.io/twitter/url/https/twitter.com/fold_left.svg?style=social&label=Follow%20%40zhinst[link="https://twitter.com/zhinst"] 6 | 7 | 8 | = Zurich Instruments LabOne API examples 9 | 10 | This repository contains various examples for controlling Zurich Instruments devices through the LabOne APIs. 11 | 12 | Only Python and Matlab examples can be found in this repository right now. Examples for other APIs will move here soon. Until then, the examples for C, .NET, and LabVIEW can be found in the https://docs.zhinst.com/labone_api/index.html[LabOne API documentation] or inside the LabOne installation. 13 | 14 | See the following sections for a detailed description on how to use the examples: 15 | 16 | * <> 17 | * <> 18 | 19 | == Project structure 20 | 21 | ---- 22 | 📒 repository 23 | 📂 hf2-mf-uhf <1> 24 | 📂 <3> 25 | 📄 example_* 26 | 📂 <2> 27 | 📂 <3> 28 | 📄 example_* 29 | 📂 utils <4> 30 | 📂 <3> 31 | ---- 32 | <1> The `hf2-mf-uhf` directory contains examples valid for HF2, MF and UHF instruments. 33 | <2> Instrument specific examples are located in the respective directory 34 | <3> Each directory is separated into the different APIs (e.g. python) 35 | <4> General helper functions are located in the `utils` directory 36 | 37 | [[python_api]] 38 | == Python API 39 | 40 | In order to run the Python examples, one needs to have the latest https://pypi.org/project/zhinst/[`zhinst`] package installed and https://www.zhinst.com/others/instruments/labone/labone-all-in-one[LabOne] up and running. 41 | (Please refer to the https://docs.zhinst.com/labone_programming_manual/overview.html[LabOne User Manual] for further information.) 42 | 43 | The Python examples are designed in a way that they can be run from the command line: 44 | 45 | [source,bash] 46 | ---- 47 | $ python path/to/example.py --help 48 | ---- 49 | 50 | Each example has a `run_example` function that contains the example source. 51 | Feel free to experiment, change or copy parts of the examples. 52 | 53 | [[matlab_api]] 54 | == Matlab API 55 | 56 | In order to run the Matlab examples, one needs to have the latest https://www.zhinst.com/others/instruments/labone/labone-all-in-one[LabOne] version installed and running. 57 | For more information to setup the Matlab API see the https://docs.zhinst.com/labone_programming_manual/matlab.html[online documentation]. 58 | 59 | To easily access the examples from within Matlab, the function `ziAddExamplePath`, located in the root of this project, adds all example subdirectories to the Matlab's path for this session. 60 | 61 | [source,matlab] 62 | ---- 63 | >> ziAddPath 64 | ---- 65 | 66 | To see all examples available run 67 | [source,matlab] 68 | ---- 69 | >> ziListExamples 70 | ---- 71 | 72 | In order to run one of the examples please perform the following steps: 73 | 74 | * Start the instrument and make sure that the correct Data Server is running 75 | (task manager on windows) 76 | * On the Instrument, connect Signal Output1 to the Signal Input1 by means of a 77 | BNC cable 78 | * Start MATLAB 79 | * Setup the LabOne in Matlab (see. https://docs.zhinst.com/labone_programming_manual/matlab.html[online documentation].) 80 | * Navigate to this folder in MATLAB 81 | * Run the MATLAB function `ziAddExamplePath.m` with the call `ziAddExamplePath` 82 | * Start an example by calling the example by name in MATLAB with your device 83 | ID as the only input argument, e.g., 84 | + 85 | [source,matlab] 86 | ---- 87 | >> example_poll('dev123') 88 | ---- 89 | -------------------------------------------------------------------------------- /shfqa/python/example_resonator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Run a frequency sweep with a SHFQA 7 | 8 | Requirements: 9 | * LabOne Version >= 21.08 10 | * Instruments: 11 | 1 x SHFQA or SHFQC Instrument 12 | * Signal output 0 connected to signal input 0 with a BNC cable. 13 | 14 | Usage: 15 | example_resonator.py [options] 16 | example_resonator.py -h | --help 17 | 18 | Arguments: 19 | The ID of the device to run the example with. [device_type: SHFQA | SHFQC] 20 | 21 | Options: 22 | -h --help Show this screen. 23 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 24 | -p --server_port PORT Port number of the data server [default: 8004] 25 | --no-plot Hide plot of the recorded data. 26 | 27 | Returns: 28 | dict Measurement result. 29 | 30 | Raises: 31 | Exception If the specified device does not match the requirements. 32 | RuntimeError If the device is not "discoverable" from the API. 33 | 34 | See the "LabOne Programming Manual" for further help, available: 35 | - On Windows via the Start-Menu: 36 | Programs -> Zurich Instruments -> Documentation 37 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 38 | sub-folder. 39 | """ 40 | 41 | import zhinst.utils 42 | from zhinst.utils.shf_sweeper import ( 43 | ShfSweeper, 44 | AvgConfig, 45 | RfConfig, 46 | SweepConfig, 47 | ) 48 | 49 | 50 | def run_example( 51 | device_id: str, 52 | server_host: str = "localhost", 53 | server_port: int = 8004, 54 | plot: bool = True, 55 | ): 56 | """run the example.""" 57 | 58 | # connect device 59 | apilevel_example = 6 60 | (daq, dev, _) = zhinst.utils.create_api_session( 61 | device_id, apilevel_example, server_host=server_host, server_port=server_port 62 | ) 63 | 64 | # instantiate ShfSweeper 65 | sweeper = ShfSweeper(daq, dev) 66 | 67 | # configure sweeper 68 | sweep_config = SweepConfig( 69 | start_freq=-200e6, 70 | stop_freq=300e6, 71 | num_points=51, 72 | mapping="linear", 73 | oscillator_gain=0.8, 74 | ) 75 | avg_config = AvgConfig(integration_time=100e-6, num_averages=2, mode="sequential") 76 | rf_config = RfConfig(channel=0, input_range=0, output_range=0, center_freq=4e9) 77 | sweeper.configure(sweep_config, avg_config, rf_config) 78 | 79 | # set to device, can also be ignored 80 | sweeper.set_to_device() 81 | 82 | # turn on the input / output channel 83 | daq.set( 84 | [ 85 | (f"/{dev}/qachannels/{rf_config.channel}/input/on", 1), 86 | (f"/{dev}/qachannels/{rf_config.channel}/output/on", 1), 87 | ] 88 | ) 89 | daq.sync() 90 | 91 | # start a sweep 92 | result = sweeper.run() 93 | print("Keys in the ShfSweeper result dictionary: ") 94 | print(result.keys()) 95 | 96 | # alternatively, get result after sweep 97 | result = sweeper.get_result() 98 | num_points_result = len(result["vector"]) 99 | print(f"Measured at {num_points_result} frequency points.") 100 | 101 | # simple plot over frequency 102 | if plot: 103 | sweeper.plot() 104 | 105 | return result 106 | 107 | 108 | if __name__ == "__main__": 109 | import sys 110 | from pathlib import Path 111 | 112 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 113 | sys.path.insert(0, str(cli_util_path)) 114 | cli_utils = __import__("cli_utils") 115 | cli_utils.run_commandline(run_example, __doc__) 116 | sys.path.remove(str(cli_util_path)) 117 | -------------------------------------------------------------------------------- /hidden/jupytext.md: -------------------------------------------------------------------------------- 1 | # Intro into JupyText 2 | 3 | [Jupytext](https://github.com/mwouts/jupytext) describes itself as the solution 4 | for working with jupyter notebooks in version control. The following 5 | instructions aim to cover the use case for this qt-code-repo and is by no means 6 | a complete documentation for jupytext. Please checkout the 7 | [documentation](https://github.com/mwouts/jupytext/tree/main/docs) of jupytext 8 | directly if you miss something in the following instructions. 9 | 10 | ## Install 11 | 12 | Install the package with pip: 13 | 14 | ``` 15 | pip install jupytext 16 | ``` 17 | 18 | ## Short overview 19 | 20 | After installing the `jupytext` package in your Python environment, depending on your editing tool, i.e., **Jupyter Lab**, **Jupyter Notebook**, and **Visual Studio Code**, you can follow one of the methods below. 21 | 22 | ### Jupyter Lab 23 | * Open a notebook in Jupyter Lab 24 | * From menu View -> Active Command Palette (Ctrl+Shift+C), select **Pair notebook with markdown** by typing pair... 25 | * Save the notebook (Ctrl+S) which should generate a paired markdown file of the same name with extension `.md` 26 | * To visualize the markdown file, right click on it and select **Open with...** and then **Jupytext Notebook** 27 | 28 | ### Jupyter Notebook 29 | * Open a notebook in Jupyter Notebook 30 | * From menu File choose Jupytext and then select **Pair Notebook with Markdown** 31 | * Save the notebook (Ctrl+S) which should generate a paired markdown file of the same name with extension `.md` 32 | 33 | ### Visual Studio Code 34 | For VS Code, two steps are required: pairing which is done once and syncing which should be done after each modification. Both steps can be done from the terminal. 35 | * To pair a Jupyter notebook with its corresponding markdown file: 36 | ``` 37 | jupytext --set-format ipynb,md ./path/to/notebook.ipynb 38 | ``` 39 | * To sync a Jupyter notebook with its corresponding markdown file: 40 | ``` 41 | jupytext --sync ./path/to/notebook.ipynb 42 | ``` 43 | 44 | ## Paring 45 | Jupytext has a feature called paired notebooks. All notebooks used in this repo 46 | should be paired with a markdown file. The benefit is that every time you change 47 | either the jupyter text or the markdown the other file will automatically adapt 48 | to the changes (on save). 49 | 50 | The [pairing](https://github.com/mwouts/jupytext/blob/main/docs/paired-notebooks.md) 51 | should happen automatically if you store a jupyter notebook file in this repository 52 | (within jupyter notebook or jupyter lab). 53 | 54 | WARNING: 55 | Simply copying the notebook into the repository does not pair it. In this 56 | case either open the notebook and store it or use the command line to set up 57 | the [paring manually](https://github.com/mwouts/jupytext/blob/main/docs/paired-notebooks.md) 58 | 59 | ## Usage 60 | Since all notebooks in this repository are paired automatically there is nothing 61 | special to consider when working with a jupyter notebook files. If you want to 62 | open an existing example stored in markdown you can simple open the markdown file 63 | in jupyter notebook and it will be automatically converted into a jupyter notebook. 64 | 65 | DANGER: 66 | The jupyter notebook integration in VSCode does not integrate jupytext. 67 | Meaning storing jupyter notebooks in vscode has no effect on the linked 68 | markdown. Either open and safe the file in the jupyter notebook directly 69 | or use the following command: 70 | 71 | >>> jupytext --sync path/to/jupyter/notebook.ipynb 72 | 73 | Jupyter notebook files are automatically ignored in git so in the diff they 74 | should not even appear. If you don`t see any changes in the corresponding markdown 75 | file make sure you have saved the notebook in the UI or sync the file manually 76 | with the following command: 77 | 78 | >>> jupytext --sync path/to/jupyter/notebook.ipynb 79 | -------------------------------------------------------------------------------- /hf2-mf-uhf/matlab/example_save_device_settings_simple.m: -------------------------------------------------------------------------------- 1 | function filename_fullpath = example_save_device_settings_simple(device_id, varargin) 2 | % EXAMPLE_SAVE_DEVICE_SETTINGS_SIMPLE Save and load device settings to and from file using utility functions 3 | % 4 | % USAGE example_save_device_settings_simple(DEVICE_ID) 5 | % 6 | % Connect to a Zurich Instruments instrument, save the instrument's settings 7 | % to file, toggle the signal output enable and reload the settings 8 | % file. Specify the device to run the example on via by DEVICE_ID, e.g., 9 | % 'dev1000' or 'uhf-dev1000'. 10 | % 11 | % This example demonstrates the use of the Utility functions ziSaveSettings() 12 | % and ziLoadSettings(). These functions will block until saving/loading has 13 | % finished (i.e., they are synchronous functions). Since this is the desired 14 | % behaviour in most cases, these utility functions are the recommended way to 15 | % save and load settings. 16 | % 17 | % If an asynchronous interface for saving and loading settings is required, 18 | % please refer to the `example_save_device_settings_expert'. Which 19 | % demonstrates how to directly use the ziDeviceSettings module. 20 | % 21 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 22 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 23 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 24 | % subfolders and run the Matlab function ziAddPath(). 25 | % >>> ziAddPath; 26 | % 27 | % Use either of the commands: 28 | % >>> help ziDAQ 29 | % >>> doc ziDAQ 30 | % in the Matlab command window to obtain help on all available ziDAQ commands. 31 | % 32 | % Copyright 2008-2018 Zurich Instruments AG 33 | 34 | clear ziDAQ; 35 | 36 | if ~exist('device_id', 'var') 37 | error(['No value for device_id specified. The first argument to the ' ... 38 | 'example should be the device ID on which to run the example, ' ... 39 | 'e.g. ''dev1000'' or ''uhf-dev1000''.']) 40 | end 41 | 42 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 43 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 44 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 45 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 46 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 47 | fprintf('On Windows this is typically:\n'); 48 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 49 | return 50 | end 51 | 52 | % The API level supported by this example. 53 | apilevel_example = 6; 54 | % Create an API session; connect to the correct Data Server for the device. 55 | [device, props] = ziCreateAPISession(device_id, apilevel_example); 56 | 57 | % Define parameters relevant to this example. Default values specified by the 58 | % inputParser below are overwritten if specified as name-value pairs via the 59 | % `varargin` input argument. 60 | p = inputParser; 61 | % The xml file (without extension) to save instrument settings to. 62 | default_filename_fullpath = [datestr(now, 'yyyymmdd_HHMM') '_settings.xml']; 63 | p.addParamValue('filename_fullpath', default_filename_fullpath, @isstr); 64 | p.parse(varargin{:}); 65 | 66 | toggleDeviceSetting(device); 67 | 68 | fprintf('Saving settings...\n'); 69 | ziSaveSettings(device, p.Results.filename_fullpath); 70 | fprintf('Saved file: ''%s''.\n', p.Results.filename_fullpath); 71 | 72 | toggleDeviceSetting(device); 73 | 74 | fprintf('Loading settings...\n'); 75 | ziLoadSettings(device, p.Results.filename_fullpath); 76 | fprintf('Done.\n'); 77 | 78 | filename_fullpath = p.Results.filename_fullpath; 79 | 80 | end 81 | 82 | 83 | function toggleDeviceSetting(device) 84 | path = ['/' device '/sigouts/0/on']; 85 | on = ziDAQ('getInt', path); 86 | if (on) 87 | on = 0; 88 | else 89 | on = 1; 90 | end 91 | fprintf('Toggling ''%s''.\n', path); 92 | ziDAQ('setInt', path, on); 93 | ziDAQ('sync'); 94 | end 95 | -------------------------------------------------------------------------------- /hidden/python/coverage_report_html.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | 3 | """ 4 | This file creates html output. 5 | """ 6 | 7 | HTML_BODY_START = """ 8 | 9 | python api examples coverage report - Zurich Instruments 10 | 11 | 12 | 29 | 30 | 31 | """ 32 | 33 | 34 | class Html: 35 | def __init__(self, filename: pathlib.Path): 36 | assert isinstance(filename, pathlib.Path) 37 | filename.parent.mkdir(parents=True, exist_ok=True) 38 | self.f = filename.open("w") 39 | 40 | def __enter__(self): 41 | self.f.write(HTML_BODY_START) 42 | return self 43 | 44 | def __exit__(self, type, value, tb): 45 | self.f.write("") 46 | self.f.close() 47 | 48 | def add_html(self, html: str) -> None: 49 | self.f.write(html) 50 | 51 | @property 52 | def table(self) -> "Table": 53 | return Table(self) 54 | 55 | @property 56 | def ul(self) -> "Ul": 57 | return Ul(self) 58 | 59 | 60 | class Table: 61 | def __init__(self, html: Html): 62 | assert isinstance(html, Html) 63 | self.f = html.f 64 | 65 | def __enter__(self): 66 | self.f.write("") 67 | return self 68 | 69 | def __exit__(self, type, value, tb): 70 | self.f.write("
") 71 | 72 | def _add_row(self, tag: str, cells: list) -> None: 73 | self.f.write(f"") 74 | self.f.write(f"<{tag}>{cells[0]}") 75 | for cell in cells[1:]: 76 | self.f.write(f"<{tag} style='text-align:center'>{cell}") 77 | self.f.write("\n") 78 | 79 | def add_header(self, cells: list) -> None: 80 | self._add_row("th", cells) 81 | 82 | def add_row(self, cells: list) -> None: 83 | self._add_row("td", cells) 84 | 85 | 86 | class Ul: 87 | def __init__(self, html: Html): 88 | assert isinstance(html, Html) 89 | self.f = html.f 90 | 91 | def __enter__(self): 92 | self.f.write("
    ") 93 | return self 94 | 95 | def __exit__(self, type, value, tb): 96 | self.f.write("
") 97 | 98 | def add_li(self, text: str) -> None: 99 | self.f.write(f"
  • {text}
  • ") 100 | 101 | 102 | if __name__ == "__main__": 103 | with Html(pathlib.Path(__file__).parent / "coverage_report_html.html") as html: 104 | html.add_html("

    python api examples coverage report

    \n") 105 | with html.table as table: 106 | table.add_header(["a", "b", "c"]) 107 | table.add_row(["a1", "b1", "c1"]) 108 | table.add_row(["a2", "b2", "c2"]) 109 | 110 | with html.ul as ul: 111 | ul.add_li("a") 112 | ul.add_li("b") 113 | 114 | html.add_html( 115 | '

    Hello velo. This is a link

    ' 116 | ) 117 | -------------------------------------------------------------------------------- /hf2-mf-uhf/matlab/test.spec.yml: -------------------------------------------------------------------------------- 1 | # every example must specify a dictionary entry. 2 | # Each example must at least contain one teste scenario or specify a skip attribute 3 | # 4 | # scenarios have the following entries: 5 | # * skip if true the scenario will be skipped (default = false) 6 | # * deviceparams define the device_id as a device type that should be used and an 7 | # optional options entry with a list of requiered options 8 | # * params optional parameter for each testcase that differ from the default value 9 | # 10 | # Demo examples: 11 | # 12 | # example_demo: 13 | # scenario_1: 14 | # deviceparams: 15 | # device_id: "MFLI" 16 | # options: ["PID","BOX"] 17 | # params: 18 | # testcase_1: 19 | # amplitude: 2 20 | # timout: 10 21 | # testcase_2: 22 | # skip: true 23 | # amplitude: 30 24 | # scenario_2: 25 | # deviceparams: 26 | # device_id: "UHFLI" 27 | # scenario_3: 28 | # skip: true 29 | # deviceparams: 30 | # device_id: "UHFLI" 31 | 32 | # example_demo: 33 | # skip: true 34 | 35 | example_connect_config: 36 | scenario_1: 37 | deviceparams: 38 | device_id: "MFLI" 39 | scenario_2: 40 | deviceparams: 41 | device_id: "UHFLI" 42 | 43 | example_connect: 44 | scenario_1: 45 | deviceparams: 46 | device_id: "MFLI" 47 | scenario_2: 48 | deviceparams: 49 | device_id: "UHFLI" 50 | 51 | example_data_acquisition_continuous: 52 | scenario_1: 53 | deviceparams: 54 | device_id: "MFLI" 55 | scenario_2: 56 | deviceparams: 57 | device_id: "UHFLI" 58 | 59 | example_data_acquisition_edge: 60 | skip: true 61 | scenario_1: 62 | deviceparams: 63 | device_id: "MFLI" 64 | scenario_2: 65 | deviceparams: 66 | device_id: "UHFLI" 67 | 68 | example_data_acquisition_fft: 69 | skip: true 70 | scenario_1: 71 | deviceparams: 72 | device_id: "MFLI" 73 | scenario_2: 74 | deviceparams: 75 | device_id: "UHFLI" 76 | 77 | example_data_acquisition_grid_average: 78 | skip: true 79 | scenario_1: 80 | deviceparams: 81 | device_id: "MFLI" 82 | scenario_2: 83 | deviceparams: 84 | device_id: "UHFLI" 85 | 86 | example_data_acquisition_grid: 87 | skip: true 88 | scenario_1: 89 | deviceparams: 90 | device_id: "MFLI" 91 | scenario_2: 92 | deviceparams: 93 | device_id: "UHFLI" 94 | 95 | example_multidevice_data_acquisition: 96 | skip: true 97 | 98 | example_multidevice_sweep: 99 | skip: true 100 | 101 | example_pid_advisor_pll: 102 | scenario_1: 103 | deviceparams: 104 | device_id: "MFLI" 105 | options: ["PID"] 106 | scenario_2: 107 | deviceparams: 108 | device_id: "UHFLI" 109 | options: ["PID"] 110 | 111 | example_poll: 112 | scenario_1: 113 | deviceparams: 114 | device_id: "MFLI" 115 | scenario_2: 116 | deviceparams: 117 | device_id: "UHFLI" 118 | 119 | example_save_device_settings_expert: 120 | scenario_1: 121 | deviceparams: 122 | device_id: "MFLI" 123 | scenario_2: 124 | deviceparams: 125 | device_id: "UHFLI" 126 | 127 | example_save_device_settings_simple: 128 | scenario_1: 129 | deviceparams: 130 | device_id: "MFLI" 131 | scenario_2: 132 | deviceparams: 133 | device_id: "UHFLI" 134 | 135 | example_scope: 136 | scenario_1: 137 | deviceparams: 138 | device_id: "MFLI" 139 | scenario_2: 140 | deviceparams: 141 | device_id: "UHFLI" 142 | 143 | example_sweeper_rstddev_fixedbw: 144 | scenario_1: 145 | deviceparams: 146 | device_id: "MFLI" 147 | scenario_2: 148 | deviceparams: 149 | device_id: "UHFLI" 150 | 151 | example_sweeper_two_demods: 152 | scenario_1: 153 | deviceparams: 154 | device_id: "MFLI" 155 | scenario_2: 156 | deviceparams: 157 | device_id: "UHFLI" 158 | 159 | example_sweeper: 160 | scenario_1: 161 | deviceparams: 162 | device_id: "MFLI" 163 | scenario_2: 164 | deviceparams: 165 | device_id: "UHFLI" 166 | -------------------------------------------------------------------------------- /shfsg/python/example_sine.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Generate a sine wave with the SHFSG Instrument. 7 | 8 | Requirements: 9 | * LabOne Version >= 22.02 10 | * Instruments: 11 | 1 x SHFSG or SHFQC Instrument 12 | 13 | Usage: 14 | example_sine.py [options] 15 | example_sine.py -h | --help 16 | 17 | Arguments: 18 | The ID of the device to run the example with. [device_type: SHFSG | SHFQC] 19 | 20 | Options: 21 | -h --help Show this screen. 22 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 23 | -p --server_port PORT Port number of the data server [default: 8004] 24 | -i --interface INTERFACE Interface between the data server and the Instrument [default: 1GbE] 25 | -c --channel ID Signal Channel. (indexed from 0) [default: 0] 26 | -r --rf_frequency FREQ Center Frequency of the synthesizer in GHz. [default: 1] 27 | -l --rflf_path VALUE Use RF (value 1) or LF (value 0) path. [default: 1] 28 | -n --osc_index ID Digital oscillator to use [default: 0] 29 | -o --osc_frequency FREQ Frequency of digital sine generator in MHz. [default: 100] 30 | -a --phase VALUE Phase of sine generator. [default: 0] 31 | -w --output_power POWER Output power in dBm, in steps of 5dBm. [default: 0] 32 | -g --gains TUPLE Gains for sine generation. [default: (0.0, 1.0, 1.0, 0.0)] 33 | 34 | Raises: 35 | Exception If the specified device does not match the requirements. 36 | RuntimeError If the device is not "discoverable" from the API. 37 | 38 | See the "LabOne Programming Manual" for further help, available: 39 | - On Windows via the Start-Menu: 40 | Programs -> Zurich Instruments -> Documentation 41 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 42 | sub-folder. 43 | """ 44 | 45 | import zhinst.core 46 | import zhinst.utils 47 | import zhinst.utils.shfsg as shfsg_utils 48 | 49 | 50 | def run_example( 51 | device_id: str, 52 | server_host: str = "localhost", 53 | server_port: int = 8004, 54 | interface: str = "1GbE", 55 | channel: int = 0, 56 | rf_frequency: float = 1, 57 | rflf_path: int = 1, 58 | osc_index: int = 0, 59 | osc_frequency: float = 100, 60 | phase: float = 0.0, 61 | output_power: float = 0, 62 | gains: tuple = (0.0, 1.0, 1.0, 0.0), 63 | ): 64 | """run the example.""" 65 | 66 | # connect device 67 | daq = zhinst.core.ziDAQServer(host=server_host, port=server_port, api_level=6) 68 | daq.connectDevice(device_id, interface) 69 | 70 | # Set analog RF center frequencies, output power, RF or LF path, enable outputs 71 | enable = 1 72 | shfsg_utils.configure_channel( 73 | daq, 74 | device_id, 75 | channel, 76 | enable=1, 77 | output_range=output_power, 78 | center_frequency=rf_frequency * 1e9, 79 | rflf_path=rflf_path, 80 | ) 81 | 82 | # Disable AWG modulation 83 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/AWG/MODULATION/ENABLE", 0) 84 | 85 | # Configure digital sine generator: oscillator index, oscillator frequency, phase, gains, enable paths 86 | shfsg_utils.configure_sine_generation( 87 | daq, 88 | device_id, 89 | channel, 90 | enable=enable, 91 | osc_index=osc_index, 92 | osc_frequency=osc_frequency * 1e6, 93 | phase=phase, 94 | gains=gains, 95 | ) 96 | 97 | print( 98 | f"Sine wave with modulation frequency {osc_frequency} MHz " 99 | f"and center frequency {rf_frequency} GHz " 100 | f"generated on channel {channel}." 101 | ) 102 | 103 | 104 | if __name__ == "__main__": 105 | import sys 106 | from pathlib import Path 107 | 108 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 109 | sys.path.insert(0, str(cli_util_path)) 110 | cli_utils = __import__("cli_utils") 111 | cli_utils.run_commandline(run_example, __doc__) 112 | sys.path.remove(str(cli_util_path)) 113 | -------------------------------------------------------------------------------- /shfqa/python/helper_resonator.py: -------------------------------------------------------------------------------- 1 | """Helper functions for the SHFQA frequency sweep examples.""" 2 | 3 | # Copyright 2021 Zurich Instruments AG 4 | 5 | import time 6 | import numpy as np 7 | 8 | import zhinst.utils.shfqa as shfqa_utils 9 | 10 | 11 | def set_trigger_loopback(daq, dev): 12 | """ 13 | Start a continuous trigger pulse from marker 1 A using the internal loopback to trigger in 1 A 14 | """ 15 | 16 | m_ch = 0 17 | low_trig = 2 18 | continuous_trig = 1 19 | daq.set( 20 | [ 21 | (f"/{dev}/raw/markers/*/testsource", low_trig), 22 | (f"/{dev}/raw/markers/{m_ch}/testsource", continuous_trig), 23 | (f"/{dev}/raw/markers/{m_ch}/frequency", 1e3), 24 | (f"/{dev}/raw/triggers/{m_ch}/loopback", 1), 25 | ] 26 | ) 27 | time.sleep(0.2) 28 | 29 | 30 | def clear_trigger_loopback(daq, dev): 31 | m_ch = 0 32 | daq.set( 33 | [ 34 | (f"/{dev}/raw/markers/*/testsource", 0), 35 | (f"/{dev}/raw/triggers/{m_ch}/loopback", 0), 36 | ] 37 | ) 38 | 39 | 40 | def measure_resonator_pulse_with_scope( 41 | daq, 42 | device_id, 43 | channel, 44 | trigger_input, 45 | pulse_length_seconds, 46 | envelope_delay=0, 47 | margin_seconds=400e-9, 48 | ): 49 | """Uses the scope to measure the pulse used for probing the resonator in pulsed spectroscopy. 50 | NOTE: this only works if the device under test transmits the signal at the 51 | selected center frequency. To obtain the actual pulse shape, the user must 52 | connect the output of the SHFQA back to the input on the same channel with 53 | a loopback cable. 54 | 55 | Arguments: 56 | daq (ziDAQServer): an instance of the zhinst.core.ziDAQServer class 57 | (representing an API session connected to a Data Server). 58 | 59 | device_id (str): the device's ID, this is the string that specifies the 60 | device's node branch in the data server's node tree. 61 | 62 | channel (int): the index of the SHFQA channel 63 | 64 | trigger_input (str): a string for selecting the trigger input 65 | Examples: "channel0_trigger_input0" or "software_trigger0" 66 | 67 | pulse_length_seconds (float): the length of the pulse to be measured in seconds 68 | 69 | envelope_delay (float): Time after the trigger that the OUT signal starts propagating 70 | 71 | margin_seconds (float): margin to add to the pulse length for the total length of the scope trace 72 | 73 | Returns: 74 | scope_trace (array): array containing the complex samples of the measured scope trace 75 | 76 | """ 77 | 78 | scope_channel = 0 79 | print("Measure the generated pulse with the SHFQA scope.") 80 | segment_duration = pulse_length_seconds + margin_seconds 81 | 82 | shfqa_utils.configure_scope( 83 | daq, 84 | device_id, 85 | input_select={scope_channel: f"channel{channel}_signal_input"}, 86 | num_samples=int(segment_duration * shfqa_utils.SHFQA_SAMPLING_FREQUENCY), 87 | trigger_input=trigger_input, 88 | num_segments=1, 89 | num_averages=1, 90 | trigger_delay=envelope_delay, 91 | ) 92 | print("Measure the generated pulse with the SHFQA scope.") 93 | print( 94 | f"NOTE: Envelope delay ({envelope_delay * 1e9:.0f} ns) is used as scope trigger delay" 95 | ) 96 | 97 | shfqa_utils.enable_scope(daq, device_id, single=1) 98 | 99 | if trigger_input == "software_trigger0": 100 | # issue a signle trigger trigger 101 | daq.set(f"/{device_id}/SYSTEM/SWTRIGGERS/0/SINGLE", 1) 102 | 103 | scope_trace, *_ = shfqa_utils.get_scope_data(daq, device_id, timeout=5) 104 | return scope_trace[scope_channel] 105 | 106 | 107 | def plot_resonator_pulse_scope_trace(scope_trace): 108 | """Plots the scope trace measured from the function `measure_resonator_pulse_with_scope`. 109 | 110 | Arguments: 111 | 112 | scope_trace (array): array containing the complex samples of the measured scope trace 113 | 114 | """ 115 | 116 | import matplotlib.pyplot as plt 117 | 118 | time_ticks_us = ( 119 | 1.0e6 * np.array(range(len(scope_trace))) / shfqa_utils.SHFQA_SAMPLING_FREQUENCY 120 | ) 121 | plt.plot(time_ticks_us, np.real(scope_trace)) 122 | plt.plot(time_ticks_us, np.imag(scope_trace)) 123 | plt.title("Resonator probe pulse") 124 | plt.xlabel(r"t [$\mu$s]") 125 | plt.ylabel("scope samples [V]") 126 | plt.legend(["real", "imag"]) 127 | plt.grid() 128 | plt.show() 129 | -------------------------------------------------------------------------------- /uhfqa/python/common_uhfqa.py: -------------------------------------------------------------------------------- 1 | """Helper functions for UHFQA examples.""" 2 | 3 | # Copyright 2018 Zurich Instruments AG 4 | 5 | import enum 6 | import numpy as np 7 | 8 | 9 | class ResultLoggingSource(enum.IntEnum): 10 | """Constants for selecting result logging source""" 11 | 12 | TRANS = 0 13 | THRES = 1 14 | ROT = 2 15 | TRANS_STAT = 3 16 | CORR_TRANS = 4 17 | CORR_THRES = 5 18 | CORR_STAT = 6 19 | 20 | 21 | def initialize_device(daq, device): 22 | """Initialize device for UHFQA examples.""" 23 | # General setup 24 | parameters = [ 25 | # Input and output ranges 26 | ("sigins/*/range", 1.5), 27 | ("sigouts/*/range", 1.5), 28 | # Set termination to 50 Ohm 29 | ("sigins/*/imp50", 1), 30 | ("sigouts/*/imp50", 1), 31 | # Turn on both outputs 32 | ("sigouts/*/on", 1), 33 | # AWG in direct mode 34 | ("awgs/*/outputs/*/mode", 0), 35 | # DIO: 36 | # - output AWG waveform as digital pattern on DIO connector 37 | ("dios/0/mode", 2), 38 | # - drive DIO bits 15 .. 0 39 | ("dios/0/drive", 2), 40 | # Delay: 41 | ("qas/0/delay", 0), 42 | # Deskew: 43 | # - straight connection: sigin 1 -- channel 1, sigin 2 -- channel 2 44 | ("qas/0/deskew/rows/0/cols/0", 1), 45 | ("qas/0/deskew/rows/0/cols/1", 0), 46 | ("qas/0/deskew/rows/1/cols/0", 0), 47 | ("qas/0/deskew/rows/1/cols/1", 1), 48 | # Results: 49 | ("qas/0/result/length", 1.0), 50 | ("qas/0/result/averages", 0), 51 | ("qas/0/result/source", ResultLoggingSource.TRANS), 52 | # Statistics: 53 | ("qas/0/result/statistics/length", 1.0), 54 | # Monitor length: 55 | ("qas/0/monitor/length", 1024), 56 | ] 57 | 58 | # Number of readout channels 59 | num_readout_channels = 10 60 | 61 | # Rotation 62 | for i in range(num_readout_channels): 63 | parameters.append((f"qas/0/rotations/{i:d}", 1 + 0j)) 64 | 65 | # Transformation 66 | # - no cross-coupling in the matrix multiplication (identity matrix) 67 | for i in range(num_readout_channels): 68 | for j in range(num_readout_channels): 69 | parameters.append((f"qas/0/crosstalk/rows/{i:d}/cols/{j:d}", int(i == j))) 70 | 71 | # Threshold 72 | for i in range(num_readout_channels): 73 | parameters.append((f"qas/0/thresholds/{i:d}/level", 1.0)) 74 | 75 | # Update device 76 | daq.set([(f"/{device:s}/{node:s}", value) for node, value in parameters]) 77 | 78 | # Set integration weights 79 | for i in range(num_readout_channels): 80 | weights = np.zeros(4096) 81 | daq.set( 82 | [ 83 | (f"/{device:s}/qas/0/integration/weights/{i:d}/real", weights), 84 | (f"/{device:s}/qas/0/integration/weights/{i:d}/imag", weights), 85 | ] 86 | ) 87 | daq.set(f"/{device:s}/qas/0/integration/length", 1) 88 | 89 | 90 | def acquisition_poll(daq, paths, num_samples, timeout=10.0): 91 | """Polls the UHFQA for data. 92 | 93 | Args: 94 | paths (list): list of subscribed paths 95 | num_samples (int): expected number of samples 96 | timeout (float): time in seconds before timeout Error is raised. 97 | """ 98 | poll_length = 1 # s 99 | poll_timeout = 5000 # ms 100 | poll_flags = 0 101 | poll_return_flat_dict = True 102 | 103 | # Keep list of recorded chunks of data for each subscribed path 104 | chunks = {p: [] for p in paths} 105 | gotem = {p: False for p in paths} 106 | 107 | # Poll data 108 | time = 0 109 | while time < timeout and not all(gotem.values()): 110 | dataset = daq.poll(poll_length, poll_timeout, poll_flags, poll_return_flat_dict) 111 | for path in paths: 112 | if path not in dataset: 113 | continue 114 | for data in dataset[path]: 115 | chunks[path].append(data["vector"]) 116 | num_obtained = sum([len(x) for x in chunks[path]]) 117 | if num_obtained >= num_samples: 118 | gotem[path] = True 119 | time += poll_length 120 | 121 | if not all(gotem.values()): 122 | for path in paths: 123 | num_obtained = sum([len(x) for x in chunks[path]]) 124 | print(f"Path {path}: Got {num_obtained} of {num_samples} samples") 125 | raise Exception( 126 | f"Timeout Error: Did not get all results within {timeout:.1f} s!" 127 | ) 128 | 129 | # Return dict of flattened data 130 | return {p: np.concatenate(v) for p, v in chunks.items()} 131 | -------------------------------------------------------------------------------- /hf2/matlab/hf2_example_autorange.m: -------------------------------------------------------------------------------- 1 | function sigin_range_auto = hf2_example_autorange(device_id, varargin) 2 | % HF2_EXAMPLE_AUTORANGE set an appropriate range for a Signal Input channel 3 | % 4 | % SIGIN_RANGE = HF2_EXAMPLE_AUTORANGE(DEVICE_ID) 5 | % 6 | % Find and set a suitable value SIGIN_RANGE for a signal input channel range 7 | % based on the values of the /devX/status/adc{0, 1}min and 8 | % /devX/status/min/adc{0, 1}max nodes. DEVICE_ID specifies the HF2 device 9 | % (DEVICE_ID should be a string, e.g., 'dev1000' or 'hf2-dev1000'). 10 | % 11 | % Returns: 12 | % 13 | % sigin_range_auto (double): the value of the signal input range as 14 | % determined by the example. The value actually set on the device is best 15 | % obtained via: ziDAQ('getDouble', ['/' device '/sigins/' channel '/range']) 16 | % 17 | % NOTE Additional configuration: Connect signal output 1 to signal input 1 18 | % with a BNC cable. 19 | % 20 | % NOTE This example can only be ran on HF2 Instruments. 21 | % 22 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 23 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 24 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 25 | % subfolders and run the Matlab function ziAddPath(). 26 | % >>> ziAddPath; 27 | % 28 | % Use either of the commands: 29 | % >>> help ziDAQ 30 | % >>> doc ziDAQ 31 | % in the Matlab command window to obtain help on all available ziDAQ commands. 32 | % 33 | % Copyright 2008-2018 Zurich Instruments AG 34 | 35 | clear ziDAQ; 36 | 37 | if ~exist('device_id', 'var') 38 | error(['No value for device_id specified. The first argument to the ' ... 39 | 'example should be the device ID on which to run the example, ' ... 40 | 'e.g. ''dev1000'' or ''hf2-dev1000''.']) 41 | end 42 | 43 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 44 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 45 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 46 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 47 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 48 | fprintf('On Windows this is typically:\n'); 49 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 50 | return 51 | end 52 | 53 | % The API level supported by this example. 54 | apilevel_example = 1; 55 | % Create an API session; connect to the correct Data Server for the device. 56 | required_err_msg = 'This example only runs with HF2 Instruments.'; 57 | [device, props] = ziCreateAPISession(device_id, apilevel_example, ... 58 | 'required_devtype', 'HF2', ... 59 | 'required_options', {}, ... 60 | 'required_err_msg', required_err_msg); 61 | 62 | %% Define parameters relevant to this example. Default values specified by the 63 | % inputParser below are overwritten if specified as name-value pairs via the 64 | % `varargin` input argument. 65 | p = inputParser; 66 | input_channels = [0, 1]; 67 | is_input_channel = @(x) assert(ismember(x, input_channels), ... 68 | 'Invalid value for input_channel: %d. Valid values: %s.', x, mat2str(input_channels)); 69 | % The Signal Input channel to use. 70 | p.addParamValue('input_channel', 0, is_input_channel); 71 | p.parse(varargin{:}); 72 | 73 | input_channel = p.Results.input_channel; 74 | 75 | %% Define some other helper variables. 76 | % The /devX/status/adc{0, 1}min and /devX/status/min/adc{0, 1}max nodes take 77 | % values between -127 and 127 78 | adc_min = -127; 79 | adc_max = 127; 80 | adc_minmax_scaling = 1.0 / 127.0; 81 | % Maximum signal input range on the HF2 82 | max_sigin_range = 2; 83 | % Time to sleep before re-checking adcmin/adcmax values 84 | time_to_sleep = 0.015; 85 | 86 | for i=0:4 87 | sigin_range = ziDAQ('getDouble', sprintf('/%s/sigins/%d/range', device, input_channel)); 88 | min_value = ziDAQ('getDouble', sprintf('/%s/status/adc%dmin', device, input_channel)); 89 | max_value = ziDAQ('getDouble', sprintf('/%s/status/adc%dmax', device, input_channel)); 90 | if (max_value >= adc_max) || (min_value <= adc_min) 91 | ziDAQ('setDouble', sprintf('/%s/sigins/%d/range', device, input_channel), max_sigin_range); 92 | sigin_range_auto = max_sigin_range; 93 | else 94 | scaling = max(abs([min_value, max_value]))*1.5*adc_minmax_scaling; 95 | % Avoid a range of 0 96 | sigin_range_auto = max([sigin_range*scaling, 1e-6]); 97 | ziDAQ('setDouble', sprintf('/%s/sigins/%d/range', device, input_channel), sigin_range_auto) 98 | ziDAQ('sync'); 99 | end 100 | pause(time_to_sleep); 101 | end 102 | 103 | end 104 | -------------------------------------------------------------------------------- /hf2-mf-uhf/matlab/example_save_device_settings_expert.m: -------------------------------------------------------------------------------- 1 | function filename_full_path = example_save_device_settings_expert(device_id, varargin) 2 | % EXAMPLE_SAVE_DEVICE_SETTINGS_EXPERT Save and load device settings to and from file with ziDAQ's deviceSettings module 3 | % 4 | % USAGE example_save_device_settings_expert(device_id) 5 | % 6 | % Demonstrate how to save and load Zurich Instruments device settings 7 | % asynchronously using the ziDeviceSettings class from the device specified by 8 | % DEVICE_ID, e.g., 'dev1000' or 'uhf-dev1000'. 9 | % 10 | % Connect to a Zurich Instruments instrument, save the instrument's settings 11 | % to file, toggle the signal output enable and reload the settings file. 12 | % 13 | % NOTE This example is intended for experienced users who require a 14 | % non-blocking (asynchronous) interface for loading and saving settings. In 15 | % general, the utility functions ziSaveSettings() and ziLoadSettings() are 16 | % more appropriate; see `example_save_device_settings_simple'. 17 | % 18 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 19 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 20 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 21 | % subfolders and run the Matlab function ziAddPath(). 22 | % >>> ziAddPath; 23 | % 24 | % Use either of the commands: 25 | % >>> help ziDAQ 26 | % >>> doc ziDAQ 27 | % in the Matlab command window to obtain help on all available ziDAQ commands. 28 | % 29 | % Copyright 2008-2018 Zurich Instruments AG 30 | 31 | clear ziDAQ; 32 | 33 | if ~exist('device_id', 'var') 34 | error(['No value for device_id specified. The first argument to the ' ... 35 | 'example should be the device ID on which to run the example, ' ... 36 | 'e.g. ''dev1000'' or ''uhf-dev1000''.']) 37 | end 38 | 39 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 40 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 41 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 42 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 43 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 44 | fprintf('On Windows this is typically:\n'); 45 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 46 | return 47 | end 48 | 49 | % The API level supported by this example. 50 | apilevel_example = 6; 51 | % Create an API session; connect to the correct Data Server for the device. 52 | [device, props] = ziCreateAPISession(device_id, apilevel_example); 53 | 54 | % Define parameters relevant to this example. Default values specified by the 55 | % inputParser below are overwritten if specified as name-value pairs via the 56 | % `varargin` input argument. 57 | p = inputParser; 58 | % The xml file (without extension) to save instrument settings to. 59 | default_filename_noext = [datestr(now, 'yyyymmdd_HHMM') '_settings']; 60 | p.addParamValue('filename_noext', default_filename_noext, @isstr); 61 | % The directory to save the settings file. Use current working directory as default. 62 | p.addParamValue('directory', ['.', filesep], @isstr); 63 | p.parse(varargin{:}); 64 | 65 | % Create a handle to access the deviceSettings thread 66 | h = ziDAQ('deviceSettings'); 67 | ziDAQ('set', h, 'device', device); 68 | 69 | toggleDeviceSetting(device); 70 | 71 | fprintf('Saving settings...\n'); 72 | ziDAQ('set', h, 'command', 'save'); 73 | ziDAQ('set', h, 'filename', p.Results.filename_noext); 74 | % Set the path to '.' to save to the current directory. Note: this 75 | % example/m-file will have to be executed in a folder where you have write access. 76 | ziDAQ('set', h, 'path', p.Results.directory); 77 | 78 | ziDAQ('execute', h); 79 | while ~ziDAQ('finished', h) 80 | pause(0.2); 81 | end 82 | 83 | settings_path = ziDAQ('getString', h, 'path'); 84 | filename_full_path = fullfile(settings_path, [p.Results.filename_noext '.xml']); 85 | fprintf('Saved file: ''%s''.\n', filename_full_path); 86 | 87 | toggleDeviceSetting(device); 88 | 89 | fprintf('Loading settings...\n'); 90 | ziDAQ('set', h, 'command', 'load'); 91 | ziDAQ('set', h, 'filename', p.Results.filename_noext); 92 | 93 | ziDAQ('execute', h); 94 | while ~ziDAQ('finished', h) 95 | pause(0.2); 96 | end 97 | fprintf('Done.\n'); 98 | 99 | % Release module resources. Especially important if modules are created 100 | % inside a loop to prevent excessive resource consumption. 101 | ziDAQ('clear', h); 102 | end 103 | 104 | 105 | function toggleDeviceSetting(device) 106 | path = ['/' device '/sigouts/0/on']; 107 | on = ziDAQ('getInt', path); 108 | if (on) 109 | on = 0; 110 | else 111 | on = 1; 112 | end 113 | fprintf('Toggling ''%s''.\n', path); 114 | ziDAQ('setInt', path, on); 115 | ziDAQ('sync'); 116 | end 117 | -------------------------------------------------------------------------------- /shfsg/python/example_rabi.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Generate a Rabi sequence with the SHFSG Instrument. 7 | 8 | Requirements: 9 | * LabOne Version >= 22.02 10 | * Instruments: 11 | 1 x SHFSG or SHFQC Instrument 12 | 13 | Usage: 14 | example_rabi.py [options] 15 | example_rabi.py -h | --help 16 | 17 | Arguments: 18 | The ID of the device to run the example with. [device_type: SHFSG | SHFQC] 19 | 20 | Options: 21 | -h --help Show this screen. 22 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 23 | -p --server_port PORT Port number of the data server [default: 8004] 24 | -i --interface INTERFACE Interface between the data server and the Instrument [default: 1GbE] 25 | -c --channel ID Signal Channel. (indexed from 0) [default: 0] 26 | -r --rf_frequency FREQ Center Frequency of the synthesizer in GHz. [default: 1] 27 | -l --rflf_path VALUE Use RF (value 1) or LF (value 0) path. [default: 1] 28 | -n --osc_index ID Digital oscillator to use [default: 0] 29 | -o --osc_frequency FREQ Frequency of digital sine generator in MHz. [default: 100] 30 | -a --phase VALUE Phase of sine generator. [default: 0] 31 | -w --output_power POWER Output power in dBm, in steps of 5dBm. [default: 0] 32 | -b --global_amp VALUE Dimensionless amplitude for scaling AWG outputs. [default: 0.5] 33 | -g --gains TUPLE Gains for sine generation. [default: (1.0, -1.0, 1.0, 1.0)] 34 | 35 | Raises: 36 | Exception If the specified device does not match the requirements. 37 | RuntimeError If the device is not "discoverable" from the API. 38 | 39 | See the "LabOne Programming Manual" for further help, available: 40 | - On Windows via the Start-Menu: 41 | Programs -> Zurich Instruments -> Documentation 42 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 43 | sub-folder. 44 | """ 45 | 46 | import os 47 | import zhinst.core 48 | import zhinst.utils 49 | import zhinst.utils.shfsg as shfsg_utils 50 | 51 | 52 | def run_example( 53 | device_id: str, 54 | server_host: str = "localhost", 55 | server_port: int = 8004, 56 | interface: str = "1GbE", 57 | channel: int = 0, 58 | rf_frequency: float = 1, 59 | rflf_path: int = 1, 60 | osc_index: int = 0, 61 | osc_frequency: float = 100, 62 | phase: float = 0.0, 63 | output_power: float = 0, 64 | global_amp: float = 0.5, 65 | gains: tuple = (1.0, -1.0, 1.0, 1.0), 66 | ): 67 | """run the example.""" 68 | 69 | # connect device 70 | daq = zhinst.core.ziDAQServer(host=server_host, port=server_port, api_level=6) 71 | daq.connectDevice(device_id, interface) 72 | 73 | # Set analog RF center frequencies, output power, RF or LF path, enable outputs 74 | shfsg_utils.configure_channel( 75 | daq, 76 | device_id, 77 | channel, 78 | enable=1, 79 | output_range=output_power, 80 | center_frequency=rf_frequency * 1e9, 81 | rflf_path=rflf_path, 82 | ) 83 | 84 | # Configure digital modulation of AWG signals 85 | shfsg_utils.configure_pulse_modulation( 86 | daq, 87 | device_id, 88 | channel, 89 | enable=1, 90 | osc_index=osc_index, 91 | osc_frequency=osc_frequency * 1e6, 92 | phase=phase, 93 | global_amp=global_amp, 94 | gains=gains, 95 | ) 96 | 97 | # Set marker source 98 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/MARKER/SOURCE", 0) 99 | 100 | # Upload sequencer programm to AWG Module 101 | with open(os.path.join(os.path.dirname(__file__), "Rabi.seq")) as f: 102 | awg_seqc = f.read() 103 | shfsg_utils.load_sequencer_program(daq, device_id, channel, awg_seqc) 104 | 105 | # Upload command table to instrument 106 | with open(os.path.join(os.path.dirname(__file__), "Rabi_command_table.json")) as f: 107 | ct_str = f.read() 108 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/AWG/COMMANDTABLE/DATA", ct_str) 109 | 110 | # Enable sequencer with single mode 111 | single = 1 112 | shfsg_utils.enable_sequencer(daq, device_id, channel, single=single) 113 | 114 | print( 115 | f"Rabi sequence with frequency {osc_frequency} MHz, center frequency {rf_frequency} GHz " 116 | f"generated on channel {channel}." 117 | ) 118 | 119 | 120 | if __name__ == "__main__": 121 | import sys 122 | from pathlib import Path 123 | 124 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 125 | sys.path.insert(0, str(cli_util_path)) 126 | cli_utils = __import__("cli_utils") 127 | cli_utils.run_commandline(run_example, __doc__) 128 | sys.path.remove(str(cli_util_path)) 129 | -------------------------------------------------------------------------------- /shfsg/python/example_cpmg.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Generate a CPMG (Carr-Purcell-Meiboom-Gill) sequence with the SHFSG Instrument. 7 | 8 | Requirements: 9 | * LabOne Version >= 22.02 10 | * Instruments: 11 | 1 x SHFSG or SHFQC Instrument 12 | 13 | Usage: 14 | example_cpmg.py [options] 15 | example_cpmg.py -h | --help 16 | 17 | Arguments: 18 | The ID of the device to run the example with. [device_type: SHFSG | SHFQC] 19 | 20 | Options: 21 | -h --help Show this screen. 22 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 23 | -p --server_port PORT Port number of the data server [default: 8004] 24 | -i --interface INTERFACE Interface between the data server and the Instrument [default: 1GbE] 25 | -c --channel ID Signal Channel. (indexed from 0) [default: 0] 26 | -r --rf_frequency FREQ Center Frequency of the synthesizer in GHz. [default: 1] 27 | -l --rflf_path VALUE Use RF (value 1) or LF (value 0) path. [default: 1] 28 | -n --osc_index ID Digital oscillator to use [default: 0] 29 | -o --osc_frequency FREQ Frequency of digital sine generator in MHz. [default: 100] 30 | -a --phase VALUE Phase of sine generator. [default: 0] 31 | -w --output_power POWER Output power in dBm, in steps of 5dBm. [default: 0] 32 | -b --global_amp VALUE Dimensionless amplitude for scaling AWG outputs. [default: 0.5] 33 | -g --gains TUPLE Gains for sine generation. [default: (1.0, -1.0, 1.0, 1.0)] 34 | 35 | Raises: 36 | Exception If the specified device does not match the requirements. 37 | RuntimeError If the device is not "discoverable" from the API. 38 | 39 | See the "LabOne Programming Manual" for further help, available: 40 | - On Windows via the Start-Menu: 41 | Programs -> Zurich Instruments -> Documentation 42 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 43 | sub-folder. 44 | """ 45 | 46 | import os 47 | import zhinst.core 48 | import zhinst.utils 49 | import zhinst.utils.shfsg as shfsg_utils 50 | 51 | 52 | def run_example( 53 | device_id: str, 54 | server_host: str = "localhost", 55 | server_port: int = 8004, 56 | interface: str = "1GbE", 57 | channel: int = 0, 58 | rf_frequency: float = 1, 59 | rflf_path: int = 1, 60 | osc_index: int = 0, 61 | osc_frequency: float = 100, 62 | phase: float = 0.0, 63 | output_power: float = 0, 64 | global_amp: float = 0.5, 65 | gains: tuple = (1.0, -1.0, 1.0, 1.0), 66 | ): 67 | """run the example.""" 68 | 69 | # connect device 70 | daq = zhinst.core.ziDAQServer(host=server_host, port=server_port, api_level=6) 71 | daq.connectDevice(device_id, interface) 72 | 73 | # Set analog RF center frequencies, output power, RF or LF path, enable outputs 74 | shfsg_utils.configure_channel( 75 | daq, 76 | device_id, 77 | channel, 78 | enable=1, 79 | output_range=output_power, 80 | center_frequency=rf_frequency * 1e9, 81 | rflf_path=rflf_path, 82 | ) 83 | 84 | # Configure digital modulation of AWG signals 85 | shfsg_utils.configure_pulse_modulation( 86 | daq, 87 | device_id, 88 | channel, 89 | enable=1, 90 | osc_index=osc_index, 91 | osc_frequency=osc_frequency * 1e6, 92 | phase=phase, 93 | global_amp=global_amp, 94 | gains=gains, 95 | ) 96 | 97 | # Set marker source 98 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/MARKER/SOURCE", 0) 99 | 100 | # Upload sequencer programm to AWG Module 101 | with open(os.path.join(os.path.dirname(__file__), "CPMG.seq")) as f: 102 | awg_seqc = f.read() 103 | shfsg_utils.load_sequencer_program(daq, device_id, channel, awg_seqc) 104 | 105 | # upload command table to instrument 106 | with open(os.path.join(os.path.dirname(__file__), "CPMG_command_table.json")) as f: 107 | ct_str = f.read() 108 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/AWG/COMMANDTABLE/DATA", ct_str) 109 | 110 | # Enable sequencer with single mode 111 | single = 1 112 | shfsg_utils.enable_sequencer(daq, device_id, channel, single=single) 113 | 114 | print( 115 | f"CPMG sequence with modulation frequency {osc_frequency} MHz, " 116 | f"center frequency {rf_frequency} GHz " 117 | f"generated on channel {channel}." 118 | ) 119 | 120 | 121 | if __name__ == "__main__": 122 | import sys 123 | from pathlib import Path 124 | 125 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 126 | sys.path.insert(0, str(cli_util_path)) 127 | cli_utils = __import__("cli_utils") 128 | cli_utils.run_commandline(run_example, __doc__) 129 | sys.path.remove(str(cli_util_path)) 130 | -------------------------------------------------------------------------------- /shfsg/python/example_ramsey.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Generate a Ramsey sequence with the SHFSG Instrument. 7 | 8 | Requirements: 9 | * LabOne Version >= 22.02 10 | * Instruments: 11 | 1 x SHFSG or SHFQC Instrument 12 | 13 | Usage: 14 | example_ramsey.py [options] 15 | example_ramsey.py -h | --help 16 | 17 | Arguments: 18 | The ID of the device to run the example with. [device_type: SHFSG | SHFQC] 19 | 20 | Options: 21 | -h --help Show this screen. 22 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 23 | -p --server_port PORT Port number of the data server [default: 8004] 24 | -i --interface INTERFACE Interface between the data server and the Instrument [default: 1GbE] 25 | -c --channel ID Signal Channel. (indexed from 0) [default: 0] 26 | -r --rf_frequency FREQ Center Frequency of the synthesizer in GHz. [default: 1] 27 | -l --rflf_path VALUE Use RF (value 1) or LF (value 0) path. [default: 1] 28 | -n --osc_index ID Digital oscillator to use [default: 0] 29 | -o --osc_frequency FREQ Frequency of digital sine generator in MHz. [default: 100] 30 | -a --phase VALUE Phase of sine generator. [default: 0] 31 | -w --output_power POWER Output power in dBm, in steps of 5dBm. [default: 0] 32 | -b --global_amp VALUE Dimensionless amplitude for scaling AWG outputs. [default: 0.5] 33 | -g --gains TUPLE Gains for sine generation. [default: (1.0, -1.0, 1.0, 1.0)] 34 | 35 | Raises: 36 | Exception If the specified device does not match the requirements. 37 | RuntimeError If the device is not "discoverable" from the API. 38 | 39 | See the "LabOne Programming Manual" for further help, available: 40 | - On Windows via the Start-Menu: 41 | Programs -> Zurich Instruments -> Documentation 42 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 43 | sub-folder. 44 | """ 45 | 46 | import os 47 | import zhinst.core 48 | import zhinst.utils 49 | import zhinst.utils.shfsg as shfsg_utils 50 | 51 | 52 | def run_example( 53 | device_id: str, 54 | server_host: str = "localhost", 55 | server_port: int = 8004, 56 | interface: str = "1GbE", 57 | channel: int = 0, 58 | rf_frequency: float = 1, 59 | rflf_path: int = 1, 60 | osc_index: int = 0, 61 | osc_frequency: float = 100, 62 | phase: float = 0.0, 63 | output_power: float = 0, 64 | global_amp: float = 0.5, 65 | gains: tuple = (1.0, -1.0, 1.0, 1.0), 66 | ): 67 | """run the example.""" 68 | 69 | # connect device 70 | daq = zhinst.core.ziDAQServer(host=server_host, port=server_port, api_level=6) 71 | daq.connectDevice(device_id, interface) 72 | 73 | # Set analog RF center frequencies, output power, RF or LF path, enable outputs 74 | shfsg_utils.configure_channel( 75 | daq, 76 | device_id, 77 | channel, 78 | enable=1, 79 | output_range=output_power, 80 | center_frequency=rf_frequency * 1e9, 81 | rflf_path=rflf_path, 82 | ) 83 | 84 | # Configure digital modulation of AWG signals 85 | shfsg_utils.configure_pulse_modulation( 86 | daq, 87 | device_id, 88 | channel, 89 | enable=1, 90 | osc_index=osc_index, 91 | osc_frequency=osc_frequency * 1e6, 92 | phase=phase, 93 | global_amp=global_amp, 94 | gains=gains, 95 | ) 96 | 97 | # Set marker source 98 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/MARKER/SOURCE", 0) 99 | 100 | # Upload sequencer programm to AWG Module 101 | with open(os.path.join(os.path.dirname(__file__), "Ramsey.seq")) as f: 102 | awg_seqc = f.read() 103 | shfsg_utils.load_sequencer_program(daq, device_id, channel, awg_seqc) 104 | 105 | # Upload command table to instrument 106 | with open( 107 | os.path.join(os.path.dirname(__file__), "Ramsey_command_table.json") 108 | ) as f: 109 | ct_str = f.read() 110 | daq.set(f"/{device_id}/SGCHANNELS/{channel}/AWG/COMMANDTABLE/DATA", ct_str) 111 | 112 | # Enable sequencer with single mode 113 | single = 1 114 | shfsg_utils.enable_sequencer(daq, device_id, channel, single=single) 115 | 116 | print( 117 | f"Ramsey sequence with modulation frequency {osc_frequency} MHz, " 118 | f"center frequency {rf_frequency} GHz " 119 | f"generated on channel {channel}." 120 | ) 121 | 122 | 123 | if __name__ == "__main__": 124 | import sys 125 | from pathlib import Path 126 | 127 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 128 | sys.path.insert(0, str(cli_util_path)) 129 | cli_utils = __import__("cli_utils") 130 | cli_utils.run_commandline(run_example, __doc__) 131 | sys.path.remove(str(cli_util_path)) 132 | -------------------------------------------------------------------------------- /hf2-mf-uhf/python/example_save_device_settings_simple.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Demonstrate how to save and load Zurich Instruments device settings using the 7 | zhinst.utils utility functions save_settings() and load_settings(). 8 | 9 | Connect to a Zurich Instruments instrument, save the instrument's settings to 10 | file, toggle the signal output enable and reload the settings file. 11 | 12 | This example demonstrates the use of the zhinst utility functions 13 | save_settings() and load_settings(). These functions will block until 14 | saving/loading has finished (i.e., they are synchronous functions). Since 15 | this is the desired behaviour in most cases, these utility functions are the 16 | recommended way to save and load settings. 17 | 18 | If an asynchronous interface for saving and loading settings is required, 19 | please refer to the `example_save_device_settings_expert'. Which 20 | demonstrates how to directly use the ziDeviceSettings module. 21 | 22 | Requirements: 23 | * LabOne Version >= 20.02 24 | * Instruments: 25 | 1 x Instrument with demodulators 26 | * signal output 1 connected to signal input 1 with a BNC cable. 27 | 28 | Usage: 29 | example_save_device_settings_simple.py [options] 30 | example_save_device_settings_simple.py -h | --help 31 | 32 | Arguments: 33 | The ID of the device [device_type: .*LI|.*IA|.*IS] 34 | 35 | Options: 36 | -h --help Show this screen. 37 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 38 | -p --server_port PORT Port number of the data server [default: None] 39 | --hf2 Flag if the used device is an HF2 instrument. (Since the HF2 uses 40 | a different data server and support only API level 1 41 | it requires minor tweaking) [default = False] 42 | --setting PATH Specify the path where to save the settings file. [default: ] 43 | 44 | Returns: 45 | filename (str) the name (with path) of the XML file where the settings were saved. 46 | 47 | Raises: 48 | Exception If the specified devices do not match the requirements. 49 | RuntimeError If the devices is not "discoverable" from the API. 50 | 51 | See the LabOne Programming Manual for further help: 52 | https://docs.zhinst.com/labone_programming_manual/ 53 | """ 54 | 55 | import time 56 | import os 57 | import zhinst.utils 58 | 59 | 60 | def run_example( 61 | device_id: str, 62 | server_host: str = "localhost", 63 | server_port: int = None, 64 | hf2: bool = False, 65 | setting: str = "", 66 | ): 67 | """run the example.""" 68 | 69 | apilevel_example = 1 if hf2 else 6 # The API level supported by this example. 70 | if not server_port: 71 | server_port = 8005 if hf2 else 8004 72 | # Call a zhinst utility function that returns: 73 | # - an API session `daq` in order to communicate with devices via the data server. 74 | # - the device ID string that specifies the device branch in the server's node hierarchy. 75 | # - the device's discovery properties. 76 | (daq, device, _) = zhinst.utils.create_api_session( 77 | device_id, apilevel_example, server_host=server_host, server_port=server_port 78 | ) 79 | 80 | timestr = time.strftime("%Y%m%d_%H%M%S") 81 | filename = ( 82 | timestr + "_example_save_device_settings_simple.xml" 83 | ) # Change this to the filename you want to save. 84 | if setting: 85 | print("setting:") 86 | print(setting) 87 | filename = setting + os.sep + filename 88 | 89 | toggle_device_setting(daq, device) 90 | 91 | # Save the instrument's current settings. 92 | print("Saving settings...") 93 | zhinst.utils.save_settings(daq, device, filename) 94 | print("Done.") 95 | 96 | # Check we actually saved the file 97 | assert os.path.isfile(filename), "Failed to save settings file '%s'" % filename 98 | print(f"Saved file '{filename}'.") 99 | 100 | toggle_device_setting(daq, device) 101 | 102 | # Load settings. 103 | print("Loading settings...") 104 | zhinst.utils.load_settings(daq, device, filename) 105 | print("Done.") 106 | 107 | return filename 108 | 109 | 110 | def toggle_device_setting(daq, device): 111 | """ 112 | Toggle a setting on the device: If it's enabled, disable the setting, and 113 | vice versa. 114 | """ 115 | path = "/%s/sigouts/0/on" % device 116 | is_enabled = daq.getInt(path) 117 | print(f"Toggling setting '{path}'.") 118 | daq.set(path, not is_enabled) 119 | daq.sync() 120 | 121 | 122 | if __name__ == "__main__": 123 | import sys 124 | from pathlib import Path 125 | 126 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 127 | sys.path.insert(0, str(cli_util_path)) 128 | cli_utils = __import__("cli_utils") 129 | cli_utils.run_commandline(run_example, __doc__) 130 | sys.path.remove(str(cli_util_path)) 131 | -------------------------------------------------------------------------------- /hf2-mf-uhf/python/test.spec.yml: -------------------------------------------------------------------------------- 1 | # For each example must be specified a dictionary entry with at least one test scenario. 2 | 3 | # Scenarios have the following entries: 4 | # * skip if true the scenario will be skipped (default = false) 5 | # * deviceparams defines which devices should be used for which variable (dev_type/option/option) 6 | # * params additional parameters for each testcase that differs from the default value 7 | 8 | # The test.spec.yml file looks like this: 9 | # 10 | # example_name1: 11 | # scenario_name1: 12 | # skip: false 13 | # deviceparams: 14 | # device_id_leader: 'HDAWG' 15 | # device_ids_follower: ['UHFLI/PID', 'MFLI/PID'] 16 | # ... 17 | # params: 18 | # testcase_name1: 19 | # amplitude: 0.1 20 | # plot: true 21 | # ... 22 | # ... 23 | # ... 24 | 25 | example_connect_config: 26 | scenario_mfli: 27 | deviceparams: 28 | device_id: "MFLI" 29 | scenario_hf2: 30 | deviceparams: 31 | device_id: "HF2LI" 32 | params: 33 | testcase_hf2: 34 | hf2: true 35 | 36 | example_connect: 37 | scenario_mfli: 38 | deviceparams: 39 | device_id: "MFLI" 40 | 41 | example_data_acquisition_continuous: 42 | scenario_mfli: 43 | deviceparams: 44 | device_id: "MFLI" 45 | 46 | example_data_acquisition_edge_fft: 47 | scenario_mfli: 48 | deviceparams: 49 | device_id: "MFLI" 50 | scenario_uhfli: 51 | deviceparams: 52 | device_id: "UHFLI" 53 | scenario_hf2: 54 | deviceparams: 55 | device_id: "HF2LI" 56 | params: 57 | testcase_hf2: 58 | hf2: true 59 | 60 | example_data_acquisition_edge: 61 | scenario_mfli: 62 | deviceparams: 63 | device_id: "MFLI" 64 | scenario_uhfli: 65 | deviceparams: 66 | device_id: "UHFLI" 67 | 68 | example_data_acquisition_grid: 69 | scenario_mfli: 70 | deviceparams: 71 | device_id: "MFLI" 72 | scenario_uhfli: 73 | deviceparams: 74 | device_id: "UHFLI" 75 | 76 | example_data_acquisition_trackingedge: 77 | scenario_mfli: 78 | deviceparams: 79 | device_id: "MFLI" 80 | scenario_uhfli: 81 | deviceparams: 82 | device_id: "UHFLI" 83 | scenario_hf2: 84 | deviceparams: 85 | device_id: "HF2LI" 86 | params: 87 | testcase_hf2: 88 | hf2: true 89 | 90 | example_multidevice_data_acquisition: 91 | scenario_uhf_mf: 92 | skip: true 93 | deviceparams: 94 | device_id_leader: "UHFLI" 95 | device_ids_follower: ["MFLI"] 96 | 97 | example_multidevice_sweep: 98 | scenario_uhf_mf: 99 | skip: true 100 | deviceparams: 101 | device_id_leader: "UHFLI" 102 | device_ids_follower: ["MFLI"] 103 | 104 | example_pid_advisor_pll: 105 | scenario_mfli: 106 | deviceparams: 107 | device_id: "MFLI/PID" 108 | scenario_uhfli: 109 | deviceparams: 110 | device_id: "UHFLI/PID" 111 | 112 | example_poll: 113 | scenario_mfli: 114 | deviceparams: 115 | device_id: "MFLI" 116 | scenario_uhfli: 117 | deviceparams: 118 | device_id: "UHFLI" 119 | scenario_hf2: 120 | deviceparams: 121 | device_id: "HF2LI" 122 | params: 123 | testcase_hf2: 124 | hf2: true 125 | 126 | example_save_device_settings_expert: 127 | scenario_mfli: 128 | deviceparams: 129 | device_id: "MFLI" 130 | params: 131 | testcase_local: 132 | setting: "." 133 | scenario_uhfli: 134 | deviceparams: 135 | device_id: "UHFLI" 136 | params: 137 | testcase_local: 138 | setting: "." 139 | 140 | example_save_device_settings_simple: 141 | scenario_mfli: 142 | deviceparams: 143 | device_id: "MFLI" 144 | scenario_uhfli: 145 | deviceparams: 146 | device_id: "UHFLI" 147 | scenario_hf2: 148 | deviceparams: 149 | device_id: "HF2LI" 150 | params: 151 | testcase_hf2: 152 | hf2: true 153 | 154 | example_scope_dig_dualchannel: 155 | scenario_mfli: 156 | deviceparams: 157 | device_id: "MFLI/DIG" 158 | scenario_uhfli: 159 | deviceparams: 160 | device_id: "UHFLI/DIG" 161 | 162 | example_scope_dig_segmented: 163 | scenario_mfli: 164 | deviceparams: 165 | device_id: "MFLI/DIG" 166 | scenario_uhfli: 167 | deviceparams: 168 | device_id: "UHFLI/DIG" 169 | 170 | example_scope_dig_stream: 171 | scenario_mfli: 172 | skip: true #TODO fails because of one of the previous examples 173 | deviceparams: 174 | device_id: "MFLI/DIG" 175 | scenario_uhfli: 176 | deviceparams: 177 | device_id: "UHFLI/DIG" 178 | 179 | example_scope: 180 | scenario_MFLI: 181 | deviceparams: 182 | device_id: "MFLI" 183 | scenario_uhfli: 184 | deviceparams: 185 | device_id: "UHFLI" 186 | 187 | example_sweeper: 188 | scenario_mfli: 189 | deviceparams: 190 | device_id: "MFLI" 191 | scenario_uhfli: 192 | deviceparams: 193 | device_id: "UHFLI" 194 | scenario_hf2: 195 | deviceparams: 196 | device_id: "HF2LI" 197 | params: 198 | testcase_hf2: 199 | hf2: true 200 | -------------------------------------------------------------------------------- /mf/matlab/example_poll_impedance.m: -------------------------------------------------------------------------------- 1 | function data = example_poll_impedance(device_id, varargin) 2 | % EXAMPLE_AUTORANGING_IMPEDANCE Demonstrate how to obtain impedance 3 | % data using ziDAQServer's blocking (synchronous) poll() command. 4 | % 5 | % USAGE DATA = EXAMPLE_POLL_IMPEDANCE(DEVICE_ID) 6 | % 7 | % The example demonstrates how to poll impedance data. 8 | % DEVICE_ID should be a string, e.g., 'dev1000'. 9 | % 10 | % NOTE Additional configuration: Connect Impedance Testfixture and attach a 1kOhm 11 | % resistor 12 | % 13 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 14 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 15 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 16 | % subfolders and run the Matlab function ziAddPath(). 17 | % >>> ziAddPath; 18 | % 19 | % Use either of the commands: 20 | % >>> help ziDAQ 21 | % >>> doc ziDAQ 22 | % in the Matlab command window to obtain help on all available ziDAQ commands. 23 | % 24 | % Copyright 2008-2018 Zurich Instruments AG 25 | 26 | clear ziDAQ; 27 | 28 | if ~exist('device_id', 'var') 29 | error(['No value for device_id specified. The first argument to the ' ... 30 | 'example should be the device ID on which to run the example, ' ... 31 | 'e.g. ''dev1000''.']) 32 | end 33 | 34 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 35 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 36 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 37 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 38 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 39 | fprintf('On Windows this is typically:\n'); 40 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 41 | return 42 | end 43 | 44 | % The API level supported by this example. 45 | apilevel_example = 6; 46 | % Create an API session; connect to the correct Data Server for the device. 47 | [device, props] = ziCreateAPISession(device_id, apilevel_example); 48 | 49 | % This example requires an MF device with IA option. 50 | if ~ismember('IA', props.options) 51 | installed_options_str = ''; % Note: strjoin() unavailable in Matlab 2009. 52 | for option=props.options 53 | installed_options_str = [installed_options_str, ' ', option{1}]; 54 | end 55 | error(['Required option set not satisfied. This example requires an MF ' ... 56 | 'Instrument with the IA Option installed. Device `%s` reports ' ... 57 | 'devtype `%s` and options `%s`.'], ... 58 | device, props.devicetype, installed_options_str); 59 | end 60 | 61 | % We use the auto-range example to perform some basic device configuration 62 | % and wait until signal input ranges have been configured by the device. 63 | example_autoranging_impedance(device); 64 | 65 | % The impedance channel to use. 66 | imp_c = '0'; 67 | imp_index = 1; 68 | 69 | % Subscribe to the impedance sample 70 | % The Data Server's node tree uses 0-based indexing; Matlab uses 71 | % 1-based indexing: 72 | imp_node_path = ['/' device, '/imps/' imp_c '/sample']; 73 | ziDAQ('subscribe', imp_node_path); 74 | 75 | % Sleep for demonstration purposes: Allow data to accumulate in the data 76 | % server's buffers for one second: poll() will not only return the data 77 | % accumulated during the specified poll_length, but also for data 78 | % accumulated since the subscribe() or the previous poll. 79 | pause(1.0); 80 | 81 | poll_duration = 0.02; 82 | poll_timeout = 100; 83 | data = ziDAQ('poll', poll_duration, poll_timeout); 84 | 85 | % Unsubscribe from all paths. 86 | ziDAQ('unsubscribe', '*'); 87 | 88 | if ziCheckPathInData(data, imp_node_path) 89 | sample = data.(device).imps(imp_index).sample; 90 | 91 | % Get the sampling rate of the device's ADCs, the device clockbase in order to convert the sample's timestamps to 92 | % seconds. 93 | clockbase = double(ziDAQ('getInt', ['/' device '/clockbase'])); 94 | t0 = double(sample.timestamp(1)); 95 | dt_seconds = (double(sample.timestamp(end)) - t0)/clockbase; 96 | num_samples= length(sample.timestamp); 97 | 98 | fprintf('Poll returned %d samples of impedance data spanning %.3f s.\n', num_samples, dt_seconds) 99 | fprintf('Average measured resistance: %.3e Ohm.\n', mean(sample.param0)) 100 | fprintf('Average measured capacitance: %.3e F.\n', mean(sample.param1)) 101 | 102 | t = (double(sample.timestamp) - t0)/clockbase; 103 | 104 | figure(1) 105 | clf; 106 | title('\\bImpedance Parameter Data'); 107 | hold on; 108 | ax1 = subplot(2, 1, 1); 109 | plot(t, sample.param0); 110 | grid on; 111 | ylabel('Resistance [Ohm]') 112 | ax2 = subplot(2, 1, 2); 113 | plot(t, sample.param1); 114 | grid on; 115 | ylabel('Capcitance [F]') 116 | xlabel('Time (s)') 117 | x = xlim(ax1); 118 | xlim(ax1, [min(x) max(x)]); 119 | linkaxes([ax1, ax2], 'x') 120 | else 121 | error(['Poll did not return the expected data (', imp_node_path, ') - data transfer rate is 0?']); 122 | end 123 | -------------------------------------------------------------------------------- /hf2-mf-uhf/python/example_save_device_settings_expert.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Demonstrate how to save and load Zurich Instruments device settings 7 | asynchronously using the ziDeviceSettings class. 8 | 9 | Note: This example is intended for experienced users who require a non-blocking 10 | (asynchronous) interface for loading and saving settings. In general, the 11 | utility functions save_settings() and load_settings() are more appropriate; see 12 | `example_save_device_settings_simple`. 13 | 14 | Requirements: 15 | * LabOne Version >= 20.02 16 | * Instruments: 17 | 1 x Instrument with demodulators 18 | * signal output 1 connected to signal input 1 with a BNC cable. 19 | 20 | Usage: 21 | example_save_device_settings_expert.py [options] 22 | example_save_device_settings_expert.py -h | --help 23 | 24 | Arguments: 25 | The ID of the device [device_type: .*LI|.*IA|.*IS] 26 | 27 | Options: 28 | -h --help Show this screen. 29 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 30 | -p --server_port PORT Port number of the data server [default: None] 31 | --hf2 Flag if the used device is an HF2 instrument. (Since the HF2 uses 32 | a different data server and support only API level 1 33 | it requires minor tweaking) [default = False] 34 | --setting PATH Specify the path where to save the settings file. [default: ] 35 | 36 | Returns: 37 | filename (str) the name (with path) of the XML file where the settings were saved. 38 | 39 | Raises: 40 | Exception If the specified devices do not match the requirements. 41 | RuntimeError If the devices is not "discoverable" from the API. 42 | 43 | See the LabOne Programming Manual for further help: 44 | https://docs.zhinst.com/labone_programming_manual/ 45 | """ 46 | 47 | import time 48 | import os 49 | import zhinst.utils 50 | 51 | 52 | def run_example( 53 | device_id: str, 54 | server_host: str = "localhost", 55 | server_port: int = None, 56 | hf2: bool = False, 57 | setting: str = "", 58 | ): 59 | """run the example.""" 60 | 61 | apilevel_example = 1 if hf2 else 6 # The API level supported by this example. 62 | if not server_port: 63 | server_port = 8005 if hf2 else 8004 64 | # Call a zhinst utility function that returns: 65 | # - an API session `daq` in order to communicate with devices via the data server. 66 | # - the device ID string that specifies the device branch in the server's node hierarchy. 67 | (daq, device, _) = zhinst.utils.create_api_session( 68 | device_id, apilevel_example, server_host=server_host, server_port=server_port 69 | ) 70 | 71 | timestr = time.strftime("%Y%m%d_%H%M%S") 72 | filename_noext = ( 73 | timestr + "_example_save_device_settings_expert" 74 | ) # Change this to the filename you want to save. 75 | 76 | device_settings = daq.deviceSettings() 77 | device_settings.set("device", device) 78 | device_settings.set("filename", filename_noext) 79 | if setting: 80 | device_settings.set("path", setting) 81 | # Set the path to '.' save to the current directory. 82 | # device_settings.set('path', '.') 83 | # NOTE: in this case, this example will have to be executed from a folder 84 | # where you have write access. 85 | 86 | toggle_device_setting(daq, device) 87 | 88 | # Save the instrument's current settings. 89 | print("Saving settings...") 90 | device_settings.set("command", "save") 91 | device_settings.execute() 92 | while not device_settings.finished(): 93 | time.sleep(0.2) 94 | print("Done.") 95 | 96 | data = device_settings.get("path") 97 | path = data["path"][0] 98 | filename_full_path = os.path.join(path, filename_noext) + ".xml" 99 | assert os.path.isfile(filename_full_path), ( 100 | "Failed to save settings file '%s'" % filename_full_path 101 | ) 102 | print(f"Saved file '{filename_full_path}'.") 103 | 104 | toggle_device_setting(daq, device) 105 | 106 | # Load the settings. 107 | print("Loading settings...") 108 | device_settings.set("command", "load") 109 | device_settings.execute() 110 | while not device_settings.finished(): 111 | time.sleep(0.2) 112 | print("Done.") 113 | 114 | return filename_full_path 115 | 116 | 117 | def toggle_device_setting(daq, device): 118 | """ 119 | Toggle a setting on the device: If it's enabled, disable the setting, and 120 | vice versa. 121 | """ 122 | path = "/%s/sigouts/0/on" % device 123 | is_enabled = daq.getInt(path) 124 | print(f"Toggling setting '{path}'.") 125 | daq.set(path, not is_enabled) 126 | daq.sync() 127 | 128 | 129 | if __name__ == "__main__": 130 | import sys 131 | from pathlib import Path 132 | 133 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 134 | sys.path.insert(0, str(cli_util_path)) 135 | cli_utils = __import__("cli_utils") 136 | cli_utils.run_commandline(run_example, __doc__) 137 | sys.path.remove(str(cli_util_path)) 138 | -------------------------------------------------------------------------------- /mf/matlab/example_autoranging_impedance.m: -------------------------------------------------------------------------------- 1 | function example_autoranging_impedance(device_id, varargin) 2 | % EXAMPLE_AUTORANGING_IMPEDANCE Demonstrate how to perform a manually triggered 3 | % autoranging for impedance while working in manual range mode. 4 | % 5 | % USAGE EXAMPLE_AUTORANGING_IMPEDANCE(DEVICE_ID) 6 | % 7 | % The example sets the device to impedance manual range mode and executes a 8 | % single auto ranging event. 9 | % DEVICE_ID should be a string, e.g., 'dev1000'. 10 | % 11 | % NOTE Additional configuration: Connect Impedance Testfixture and attach a 1kOhm 12 | % resistor 13 | % 14 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 15 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 16 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 17 | % subfolders and run the Matlab function ziAddPath(). 18 | % >>> ziAddPath; 19 | % 20 | % Use either of the commands: 21 | % >>> help ziDAQ 22 | % >>> doc ziDAQ 23 | % in the Matlab command window to obtain help on all available ziDAQ commands. 24 | % 25 | % Copyright 2008-2016 Zurich Instruments AG 26 | 27 | clear ziDAQ; 28 | 29 | if ~exist('device_id', 'var') 30 | error(['No value for device_id specified. The first argument to the ' ... 31 | 'example should be the device ID on which to run the example, ' ... 32 | 'e.g. ''dev1000''.']) 33 | end 34 | 35 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 36 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 37 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 38 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 39 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 40 | fprintf('On Windows this is typically:\n'); 41 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 42 | return 43 | end 44 | 45 | % The API level supported by this example. 46 | apilevel_example = 6; 47 | % Create an API session; connect to the correct Data Server for the device. 48 | [device, props] = ziCreateAPISession(device_id, apilevel_example); 49 | 50 | % This example requires an MF device with IA option. 51 | if ~ismember('IA', props.options) 52 | installed_options_str = ''; % Note: strjoin() unavailable in Matlab 2009. 53 | for option=props.options 54 | installed_options_str = [installed_options_str, ' ', option{1}]; 55 | end 56 | error(['Required option set not satisfied. This example requires an MF ' ... 57 | 'Instrument with the IA Option installed. Device `%s` reports ' ... 58 | 'devtype `%s` and options `%s`.'], ... 59 | device, props.devicetype, installed_options_str); 60 | end 61 | 62 | % Create a base configuration: Disable all available outputs, awgs, 63 | % demods, scopes,... 64 | ziDisableEverything(device); 65 | 66 | imp_c = '0'; 67 | curr_c = mat2str(ziDAQ('getInt', ['/' device '/imps/' imp_c '/current/inputselect'])); 68 | volt_c = mat2str(ziDAQ('getInt', ['/' device '/imps/' imp_c '/voltage/inputselect'])); 69 | man_curr_range = 10e-3; 70 | man_volt_range = 10e-3; 71 | 72 | %% Configure the device ready for this experiment. 73 | % The following channels and indices work on all devices with IA option. The 74 | % values below may be changed if the instrument has multiple IA modules. 75 | ziDAQ('setInt', ['/' device '/imps/' imp_c '/enable'], 1); 76 | ziDAQ('setInt', ['/' device '/imps/' imp_c '/mode'], 0); 77 | ziDAQ('setInt', ['/' device '/imps/' imp_c '/auto/output'], 1); 78 | ziDAQ('setInt', ['/' device '/imps/' imp_c '/auto/bw'], 1); 79 | ziDAQ('setDouble', ['/' device '/imps/' imp_c '/freq'], 500); 80 | ziDAQ('setInt', ['/' device '/imps/' imp_c '/auto/inputrange'], 0); 81 | ziDAQ('setDouble', ['/' device '/currins/' curr_c '/range'], man_curr_range); 82 | ziDAQ('setDouble', ['/' device '/sigins/' volt_c '/range'], man_volt_range); 83 | ziDAQ('sync'); 84 | 85 | %% Trigger an autoranging 86 | % Afater setting the device in impedance manual mode we trigger a single auto 87 | % ranging event and wait until it is finished 88 | fprintf('Start auto ranging. This might take a few seconds.\n'); 89 | ziDAQ('setInt', ['/' device '/currins/' curr_c '/autorange'], 1); 90 | ziDAQ('setInt', ['/' device '/sigins/' volt_c '/autorange'], 1); 91 | ziDAQ('sync'); 92 | currins_autorange = 1; 93 | sigins_autorange = 1; 94 | timeout = 20; 95 | t0 = tic; 96 | while currins_autorange || sigins_autorange 97 | if toc(t0) > timeout 98 | error('Autoranging failed to completed after %.2f s.\n', timeout); 99 | end 100 | pause(0.2); 101 | currins_autorange = ziDAQ('getInt', ['/' device '/currins/' curr_c '/autorange']); 102 | sigins_autorange = ziDAQ('getInt', ['/' device '/sigins/' volt_c '/autorange']); 103 | end 104 | 105 | fprintf('Auto ranging finished after %.1f s.\n', toc(t0)); 106 | auto_curr_range = ziDAQ('getDouble', ['/' device '/currins/' curr_c '/range']); 107 | auto_volt_range = ziDAQ('getDouble', ['/' device '/sigins/' volt_c '/range']); 108 | fprintf('Current range changed from %0.1eA to %0.1eA.\n', man_curr_range, auto_curr_range); 109 | fprintf('Voltage range changed from %0.1eV to %0.1eV.\n', man_volt_range, auto_volt_range); 110 | -------------------------------------------------------------------------------- /shfqa/python/example_qubit_readout_measurement.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Does a parallel read-out of 8 qubits. 7 | 8 | Requirements: 9 | * LabOne Version >= 22.02 10 | * Instruments: 11 | 1 x SHFQA or SHFQC Instrument 12 | * Loopback configuration between input and output of channel 0 13 | 14 | Usage: 15 | example_qubit_readout_measurement.py [options] 16 | example_qubit_readout_measurement.py -h | --help 17 | 18 | Arguments: 19 | The ID of the device to run the example with. [device_type: SHFQA | SHFQC] 20 | 21 | Options: 22 | -h --help Show this screen. 23 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 24 | -p --server_port PORT Port number of the data server [default: 8004] 25 | --no-plot Hide plot of the recorded data. 26 | 27 | Returns: 28 | dict complex readout data 29 | 30 | Raises: 31 | Exception If the specified device does not match the requirements. 32 | RuntimeError If the device is not "discoverable" from the API. 33 | 34 | See the "LabOne Programming Manual" for further help, available: 35 | - On Windows via the Start-Menu: 36 | Programs -> Zurich Instruments -> Documentation 37 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 38 | sub-folder. 39 | """ 40 | 41 | import numpy as np 42 | import zhinst.utils 43 | import zhinst.utils.shfqa as shfqa_utils 44 | import helper_qubit_readout as helper 45 | import helper_commons 46 | 47 | 48 | def run_example( 49 | device_id: str, 50 | server_host: str = "localhost", 51 | server_port: int = 8004, 52 | plot: bool = True, 53 | ): 54 | """run the example.""" 55 | 56 | # connect device 57 | apilevel_example = 6 58 | (daq, _, _) = zhinst.utils.create_api_session( 59 | device_id, apilevel_example, server_host=server_host, server_port=server_port 60 | ) 61 | 62 | # define parameters 63 | channel_index = 0 64 | num_qubits = 8 65 | num_readouts = 100 66 | 67 | # configure inputs and outputs 68 | shfqa_utils.configure_channel( 69 | daq, 70 | device_id, 71 | channel_index, 72 | center_frequency=5e9, 73 | input_range=0, 74 | output_range=-5, 75 | mode="readout", 76 | ) 77 | # enable qachannel 78 | path = f"/{device_id}/qachannels/{channel_index}/" 79 | daq.set( 80 | [ 81 | (path + "input/on", 1), 82 | (path + "output/on", 1), 83 | ] 84 | ) 85 | 86 | # generate and upload waveforms 87 | scaling = 0.9 / num_qubits 88 | readout_pulses = helper_commons.generate_flat_top_gaussian( 89 | frequencies=np.linspace(32e6, 230e6, num_qubits), 90 | pulse_duration=500e-9, 91 | rise_fall_time=10e-9, 92 | sampling_rate=shfqa_utils.SHFQA_SAMPLING_FREQUENCY, 93 | scaling=scaling, 94 | ) 95 | shfqa_utils.write_to_waveform_memory( 96 | daq, device_id, channel_index, waveforms=readout_pulses 97 | ) 98 | 99 | # configure result logger and weighted integration 100 | weights = helper.generate_integration_weights(readout_pulses) 101 | shfqa_utils.configure_weighted_integration( 102 | daq, 103 | device_id, 104 | channel_index, 105 | weights=weights, 106 | # compensation for the delay between generator output and input of the integration unit 107 | integration_delay=200e-9, 108 | ) 109 | shfqa_utils.configure_result_logger_for_readout( 110 | daq, 111 | device_id, 112 | channel_index, 113 | result_source="result_of_integration", 114 | result_length=num_readouts, 115 | ) 116 | 117 | # configure sequencer 118 | shfqa_utils.configure_sequencer_triggering( 119 | daq, device_id, channel_index, aux_trigger="software_trigger0" 120 | ) 121 | seqc_program = helper.generate_sequencer_program( 122 | num_measurements=num_readouts, task="dig_trigger_play_all" 123 | ) 124 | shfqa_utils.load_sequencer_program( 125 | daq, device_id, channel_index, sequencer_program=seqc_program 126 | ) 127 | 128 | # run experiment 129 | shfqa_utils.enable_result_logger(daq, device_id, channel_index, mode="readout") 130 | shfqa_utils.enable_sequencer(daq, device_id, channel_index, single=1) 131 | # Note: software triggering is used for illustration purposes only. Use a real 132 | # trigger source for actual experiments 133 | shfqa_utils.start_continuous_sw_trigger( 134 | daq, device_id, num_triggers=num_readouts, wait_time=2e-3 135 | ) 136 | 137 | # get and plot results 138 | readout_results = shfqa_utils.get_result_logger_data( 139 | daq, device_id, channel_index, mode="readout" 140 | ) 141 | 142 | if plot: 143 | helper.plot_readout_results(readout_results[:num_qubits]) 144 | 145 | return readout_results[:num_qubits] 146 | 147 | 148 | if __name__ == "__main__": 149 | import sys 150 | from pathlib import Path 151 | 152 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 153 | sys.path.insert(0, str(cli_util_path)) 154 | cli_utils = __import__("cli_utils") 155 | cli_utils.run_commandline(run_example, __doc__) 156 | sys.path.remove(str(cli_util_path)) 157 | -------------------------------------------------------------------------------- /mf/python/example_autoranging_impedance.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Demonstrate how to perform a manually triggered autoranging for impedance while working in 7 | manual range mode. Sets the device to impedance manual range mode and execute 8 | a single auto ranging event. 9 | 10 | Requirements: 11 | * LabOne Version >= 20.02 12 | * Instruments: 13 | 1 x Instrument with IA option 14 | * Connect Impedance Testfixture and attach a 1kOhm resistor 15 | 16 | Usage: 17 | example_autoranging_impedance.py [options] 18 | example_autoranging_impedance.py -h | --help 19 | 20 | Arguments: 21 | The ID of the device [device_type: MF*(IA)] 22 | 23 | Options: 24 | -h --help Show this screen. 25 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 26 | -p --server_port PORT Port number of the data server [default: 8004] 27 | 28 | Raises: 29 | Exception If the specified devices do not match the requirements. 30 | RuntimeError If the devices is not "discoverable" from the API. 31 | 32 | See the LabOne Programming Manual for further help: 33 | https://docs.zhinst.com/labone_programming_manual/ 34 | """ 35 | 36 | import time 37 | import zhinst.utils 38 | 39 | 40 | def run_example( 41 | device_id: str, 42 | server_host: str = "localhost", 43 | server_port: int = 8004, 44 | ): 45 | """run the example.""" 46 | 47 | apilevel_example = 6 # The API level supported by this example. 48 | # Call a zhinst utility function that returns: 49 | # - an API session `daq` in order to communicate with devices via the data server. 50 | # - the device ID string that specifies the device branch in the server's node hierarchy. 51 | # - the device's discovery properties. 52 | (daq, device, _) = zhinst.utils.create_api_session( 53 | device_id, apilevel_example, server_host=server_host, server_port=server_port 54 | ) 55 | 56 | # Create a base configuration: disable all available outputs, awgs, demods, scopes,... 57 | zhinst.utils.disable_everything(daq, device) 58 | 59 | # Now configure the instrument for this experiment. The following channels 60 | # and indices work on all devices with IA option. The values below may be 61 | # changed if the instrument has multiple IA modules. 62 | imp_index = 0 63 | curr_index = daq.getInt("/%s/imps/%d/current/inputselect" % (device, imp_index)) 64 | volt_index = daq.getInt("/%s/imps/%d/voltage/inputselect" % (device, imp_index)) 65 | man_curr_range = 10e-3 66 | man_volt_range = 10e-3 67 | exp_settings = [ 68 | ["/%s/imps/%d/enable" % (device, imp_index), 1], 69 | ["/%s/imps/%d/mode" % (device, imp_index), 0], 70 | ["/%s/imps/%d/auto/output" % (device, imp_index), 1], 71 | ["/%s/imps/%d/auto/bw" % (device, imp_index), 1], 72 | ["/%s/imps/%d/freq" % (device, imp_index), 500], 73 | ["/%s/imps/%d/auto/inputrange" % (device, imp_index), 0], 74 | ["/%s/currins/%d/range" % (device, curr_index), man_curr_range], 75 | ["/%s/sigins/%d/range" % (device, volt_index), man_volt_range], 76 | ] 77 | daq.set(exp_settings) 78 | # Perform a global synchronisation between the device and the data server: 79 | # Ensure that the settings have taken effect on the device before setting 80 | # the next configuration. 81 | daq.sync() 82 | 83 | # After setting the device in manual ranging mode we want to trigger manually 84 | # a one time auto ranging to find a suitable range. Therefore, we trigger the 85 | # auto ranging for the current input as well as for the voltage input. 86 | trigger_auto_ranging = [ 87 | ["/%s/currins/%d/autorange" % (device, curr_index), 1], 88 | ["/%s/sigins/%d/autorange" % (device, volt_index), 1], 89 | ] 90 | print("Start auto ranging. This takes a few seconds.") 91 | daq.set(trigger_auto_ranging) 92 | 93 | t_start = time.time() 94 | timeout = 20 95 | finished = 0 96 | # The auto ranging takes some time. We do not want to continue before the 97 | # best range is found. Therefore, we implement a loop to check if the auto 98 | # ranging is finished. These nodes maintain value 1 until autoranging has 99 | # finished. 100 | while not finished: 101 | time.sleep(0.5) 102 | currins_autorange = daq.getInt( 103 | "/%s/currins/%d/autorange" % (device, curr_index) 104 | ) 105 | sigins_autorange = daq.getInt("/%s/sigins/%d/autorange" % (device, volt_index)) 106 | # We are finished when both nodes have been set back to 0 by the device. 107 | finished = (currins_autorange == 0) and (sigins_autorange == 0) 108 | if time.time() - t_start > timeout: 109 | raise Exception(f"Autoranging failed after {timeout} seconds.") 110 | print(f"Auto ranging finished after {time.time() - t_start:0.1f} s.") 111 | 112 | auto_curr_range = daq.getDouble("/%s/currins/%d/range" % (device, curr_index)) 113 | auto_volt_range = daq.getDouble("/%s/sigins/%d/range" % (device, volt_index)) 114 | print( 115 | f"Current range changed from {man_curr_range:0.1e} A to {auto_curr_range:0.1e} A." 116 | ) 117 | print( 118 | f"Voltage range changed from {man_volt_range:0.1e} V to {auto_volt_range:0.1e} V." 119 | ) 120 | 121 | 122 | if __name__ == "__main__": 123 | import sys 124 | from pathlib import Path 125 | 126 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 127 | sys.path.insert(0, str(cli_util_path)) 128 | cli_utils = __import__("cli_utils") 129 | cli_utils.run_commandline(run_example, __doc__) 130 | sys.path.remove(str(cli_util_path)) 131 | -------------------------------------------------------------------------------- /hf2-mf-uhf/matlab/example_connect_config.m: -------------------------------------------------------------------------------- 1 | function r = example_connect_config(device_id, varargin) 2 | % EXAMPLE_CONNECT_CONFIG Connect to and configure a Zurich Instruments device 3 | % 4 | % USAGE R = EXAMPLE_CONNECT_CONFIG(DEVICE_ID) 5 | % 6 | % Connect to the Zurich Instruments instrument specified by DEVICE_ID, obtain 7 | % a single demodulator sample and calculate its RMS amplitude R. DEVICE_ID 8 | % should be a string, e.g., 'dev1000' or 'uhf-dev1000'. 9 | % 10 | % NOTE Additional configuration: Connect signal output 1 to signal input 1 11 | % with a BNC cable. 12 | % 13 | % NOTE This is intended to be a simple example demonstrating how to connect 14 | % to a Zurich Instruments device from ziPython. In most cases, data acquistion 15 | % should use either ziDAQServer's poll() method or an instance of the 16 | % ziDAQRecorder class. 17 | % 18 | % NOTE Please ensure that the ziDAQ folders 'Driver' and 'Utils' are in your 19 | % Matlab path. To do this (temporarily) for one Matlab session please navigate 20 | % to the ziDAQ base folder containing the 'Driver', 'Examples' and 'Utils' 21 | % subfolders and run the Matlab function ziAddPath(). 22 | % >>> ziAddPath; 23 | % 24 | % Use either of the commands: 25 | % >>> help ziDAQ 26 | % >>> doc ziDAQ 27 | % in the Matlab command window to obtain help on all available ziDAQ commands. 28 | % 29 | % See also EXAMPLE_CONNECT, EXAMPLE_POLL. 30 | % 31 | % Copyright 2008-2018 Zurich Instruments AG 32 | 33 | clear ziDAQ; 34 | 35 | if ~exist('device_id', 'var') 36 | error(['No value for device_id specified. The first argument to the ' ... 37 | 'example should be the device ID on which to run the example, ' ... 38 | 'e.g. ''dev1000'' or ''uhf-dev1000''.']) 39 | end 40 | 41 | % Check the ziDAQ MEX (DLL) and Utility functions can be found in Matlab's path. 42 | if ~(exist('ziDAQ') == 3) && ~(exist('ziCreateAPISession', 'file') == 2) 43 | fprintf('Failed to either find the ziDAQ mex file or ziDevices() utility.\n') 44 | fprintf('Please configure your path using the ziDAQ function ziAddPath().\n') 45 | fprintf('This can be found in the API subfolder of your LabOne installation.\n'); 46 | fprintf('On Windows this is typically:\n'); 47 | fprintf('C:\\Program Files\\Zurich Instruments\\LabOne\\API\\MATLAB2012\\\n'); 48 | return 49 | end 50 | 51 | % The API level supported by this example. 52 | apilevel_example = 6; 53 | % Create an API session; connect to the correct Data Server for the device. 54 | [device, props] = ziCreateAPISession(device_id, apilevel_example); 55 | 56 | branches = ziDAQ('listNodes', ['/' device ], 0); 57 | if ~any(strcmpi([branches], 'DEMODS')) 58 | r = nan; 59 | fprintf('\nThis example requires lock-in functionality which is not available on %s.\n', device); 60 | return 61 | end 62 | 63 | % Define parameters relevant to this example. Default values specified by the 64 | % inputParser are overwritten if specified via `varargin`. 65 | p = inputParser; 66 | % The signal output mixer amplitude, [V]. 67 | p.addParamValue('amplitude', 0.5, @isnumeric); 68 | p.parse(varargin{:}); 69 | amplitude = p.Results.amplitude; 70 | 71 | % Define some other helpful parameters. 72 | demod_c = '0'; % demod channel 73 | out_c = '0'; % signal output channel 74 | % Get the value of the instrument's default Signal Output mixer channel. 75 | out_mixer_c = num2str(ziGetDefaultSigoutMixerChannel(props, str2num(out_c))); 76 | in_c = '0'; % signal input channel 77 | osc_c = '0'; % oscillator 78 | time_constant = 0.001; % [s] 79 | demod_rate = 2e3; 80 | 81 | % Create a base configuration: Disable all available outputs, awgs, 82 | % demods, scopes,... 83 | ziDisableEverything(device); 84 | 85 | %% Configure the device ready for this experiment. 86 | ziDAQ('setInt', ['/' device '/sigins/' in_c '/imp50'], 0); 87 | ziDAQ('setInt', ['/' device '/sigins/' in_c '/ac'], 0); 88 | ziDAQ('setDouble', ['/' device '/sigins/' in_c '/range'], 2); 89 | ziDAQ('setInt', ['/' device '/sigouts/' out_c '/on'], 1); 90 | ziDAQ('setDouble', ['/' device '/sigouts/' out_c '/range'], 1); 91 | ziDAQ('setDouble', ['/' device '/sigouts/' out_c '/amplitudes/' out_mixer_c], amplitude); 92 | ziDAQ('setDouble', ['/' device '/sigouts/' out_c '/enables/' out_mixer_c], 1); 93 | if strfind(props.devicetype, 'HF2') 94 | ziDAQ('setInt', ['/' device '/sigins/' in_c '/diff'], 0); 95 | ziDAQ('setInt', ['/' device '/sigouts/' out_c '/add'], 0); 96 | end 97 | ziDAQ('setDouble', ['/' device '/demods/*/phaseshift'], 0); 98 | ziDAQ('setInt', ['/' device '/demods/*/order'], 8); 99 | ziDAQ('setDouble', ['/' device '/demods/' demod_c '/rate'], demod_rate); 100 | ziDAQ('setInt', ['/' device '/demods/' demod_c '/harmonic'], 1); 101 | ziDAQ('setInt', ['/' device '/demods/' demod_c '/enable'], 1); 102 | ziDAQ('setInt', ['/' device '/demods/*/oscselect'], str2double(osc_c)); 103 | ziDAQ('setInt', ['/' device '/demods/*/adcselect'], str2double(in_c)); 104 | 105 | ziDAQ('setDouble', ['/' device '/demods/*/timeconstant'], time_constant); 106 | ziDAQ('setDouble', ['/' device '/oscs/' osc_c '/freq'], 400e3); % [Hz] 107 | 108 | % Unsubscribe from any streaming data 109 | ziDAQ('unsubscribe', '*'); 110 | 111 | % Pause to get a settled demodulator filter 112 | pause(10*time_constant); 113 | 114 | % Perform a global synchronisation between the device and the data server: 115 | % Ensure that the settings have taken effect on the device before issuing the 116 | % ``getSample`` command. Note: ``sync`` must be issued after waiting for the 117 | % demodulator filter to settle above. 118 | ziDAQ('sync'); 119 | 120 | % Get a single demodulator sample. Note, `poll` or other higher-level 121 | % functionality should almost always be be used instead of `getSample`. 122 | sample = ziDAQ('getSample', ['/' device '/demods/0/sample']); 123 | r = abs(sample.x + j*sample.y); 124 | fprintf('Measured RMS amplitude: %fV.\n', r) 125 | 126 | end 127 | -------------------------------------------------------------------------------- /ghfli/matlab/example_ghfli_sweeper.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2023 Zurich Instruments AG 3 | % This example demonstrates how to obtain a Bode plot using the Sweeper 4 | % module for the GHFLI Lock-in Amplifier. 5 | 6 | % Clear and close everything 7 | close all; clear; clc; 8 | 9 | %% User settings --------------------------------------------------------- 10 | 11 | % Serial number of instrument in its rear panel. 12 | device = 'dev10000'; 13 | 14 | % Interface between the instrument and the host computer: '1GbE' 15 | interface = '1GbE'; 16 | 17 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 18 | host = 'localhost'; 19 | 20 | % Sweep parameters 21 | start_frequency = 100e6; % [Hz] 22 | stop_frequency = 1400e6; % [Hz] 23 | num_points = 50; % Number of frequency points 24 | 25 | %% Connection to instrument ---------------------------------------------- 26 | 27 | % Close current API sessions 28 | clear ziDAQ 29 | 30 | % Create an API session to the data server 31 | port = 8004; % Data server port to communicate 32 | api_level = 6; % Maximum API level supported by the instrument 33 | ziDAQ('connect', host, port, api_level); 34 | 35 | % Establish a connection between data server and instrument 36 | ziDAQ('connectDevice', device, interface); 37 | 38 | %% Instrument settings --------------------------------------------------- 39 | 40 | % Define all the settings in a cell 41 | device_settings = { 42 | % Adjust the data rate of demodulator 1 43 | ['/' device '/demods/0/rate'], 10e3 44 | % Enable continuous data streaming of demodulator 1 45 | ['/' device '/demods/0/trigger/triggeracq'], 0 46 | % Enable the data transfer from demodulator 1 to data server 47 | ['/' device '/demods/0/enable'], 1 48 | }; 49 | 50 | % Apply all the settings to the device via a transaction 51 | ziDAQ('set', device_settings); 52 | 53 | %% Sweeper module -------------------------------------------------------- 54 | 55 | % Create an instance of the Sweeper Module 56 | sweeper = ziDAQ('sweep'); 57 | 58 | % Assign the instrument to the sweeper object (must be set first) 59 | ziDAQ('set', sweeper, 'device', device); 60 | 61 | % Specify that the frequency of oscillator 1 should be swept 62 | ziDAQ('set', sweeper, 'gridnode', ['/' device '/oscs/0/freq']); 63 | 64 | % Set the start and stop values of the sweeping parameter 65 | ziDAQ('set', sweeper, 'start', start_frequency); 66 | ziDAQ('set', sweeper, 'stop', stop_frequency); 67 | 68 | % Set the number of points in the sweep range 69 | ziDAQ('set', sweeper, 'samplecount', num_points); 70 | 71 | % Sequential sweep from start to stop points 72 | ziDAQ('set', sweeper, 'scan', 'sequential'); 73 | 74 | % Linear scale of sweeping parameter (frequency) 75 | ziDAQ('set', sweeper, 'xmapping', 'linear'); 76 | 77 | % Automatic control of demodulation bandwidth 78 | ziDAQ('set', sweeper, 'bandwidthcontrol', 2); 79 | 80 | % Demodulation filter order 81 | ziDAQ('set', sweeper, 'order', 3); 82 | 83 | % Maximum measurement bandwidth [Hz] 84 | ziDAQ('set', sweeper, 'maxbandwidth', 4.0e3); 85 | 86 | % Single-sweep mode 87 | ziDAQ('set', sweeper, 'endless', 0); 88 | 89 | %% Subscription to signal path ------------------------------------------- 90 | 91 | % Subscribe to the signal path of demodulator 1 for acquisition 92 | path = ['/' device '/demods/0/sample']; 93 | ziDAQ('subscribe', sweeper, path); 94 | 95 | %% Run sweeper ----------------------------------------------------------- 96 | 97 | fprintf('\nStart sweeping frequency...\n\n'); 98 | 99 | % Start the sweep 100 | ziDAQ('execute', sweeper); 101 | 102 | sweep_completed = true; 103 | timeout = 30; 104 | t0 = tic; 105 | %while ziDAQ('progress', sweeper) < 1.0 && ~ziDAQ('finished', sweeper) 106 | while ~ziDAQ('finished', sweeper) 107 | pause(1); 108 | fprintf('Progress %0.0f%%\n', ziDAQ('progress', sweeper) * 100); 109 | if toc(t0) > timeout 110 | sweep_completed = false; 111 | break; 112 | end 113 | end 114 | ziDAQ('finish', sweeper); 115 | ziDAQ('unsubscribe', sweeper, '*'); 116 | 117 | if sweep_completed 118 | fprintf('\nSweeper finished within %.1f s.\n\n', toc(t0)); 119 | else 120 | fprintf('\nTimeout: Sweeper could not finish within %.1f s.\n\n', timeout); 121 | end 122 | 123 | % Read out the data acquired by the sweeper 124 | data = ziDAQ('read', sweeper); 125 | 126 | % Destroy the sweeper object 127 | ziDAQ('clear', sweeper); 128 | 129 | %% Disconnection --------------------------------------------------------- 130 | 131 | % Disconnect the device from data server 132 | % ziDAQ('disconnectDevice', device); 133 | 134 | % Destroy the API session 135 | clear ziDAQ 136 | 137 | %% Plotting -------------------------------------------------------------- 138 | 139 | if sweep_completed 140 | 141 | % Extract signal frequency, amplitude and phase 142 | sample = data.(device).demods(1).sample{1,1}; 143 | freq = sample.grid; 144 | amp = sample.r; 145 | phase = sample.phase; 146 | 147 | % Visualization 148 | figure('Name','Bode','NumberTitle','on'); 149 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 150 | subplot(2,1,1) 151 | h = plot(freq * 1e-6, amp); 152 | set(h,'LineWidth',1,'LineStyle','-','Color',[0 0.4470 0.7410]) 153 | xlabel('Frequency (MHz)','fontsize',10,'fontweight','n','color','k'); 154 | ylabel('Amplitude (V)','fontsize',10,'fontweight','n','color','k'); 155 | xlim([start_frequency stop_frequency] * 1e-6); 156 | grid on 157 | title('Frequency Response: Amplitude and Phase') 158 | subplot(2,1,2) 159 | h = plot(freq * 1e-6, (180/pi)*phase); 160 | set(h,'LineWidth',1 ,'LineStyle','-','Color',[0.6350 0.0780 0.1840]) 161 | xlabel('Frequency (MHz)','fontsize',10,'fontweight','n','color','k'); 162 | ylabel('Phase (deg)','fontsize',10,'fontweight','n','color','k'); 163 | xlim([start_frequency stop_frequency] * 1e-6); 164 | grid on 165 | 166 | end 167 | % ------------------------------------------------------------------------ 168 | -------------------------------------------------------------------------------- /shfli/matlab/example_shfli_sweeper.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2023 Zurich Instruments AG 3 | % This example demonstrates how to obtain a Bode plot using the Sweeper 4 | % module for the SHFLI Lock-in Amplifier. 5 | 6 | % Clear and close everything 7 | close all; clear; clc; 8 | 9 | %% User settings --------------------------------------------------------- 10 | 11 | % Serial number of instrument in its rear panel. 12 | device = 'dev10000'; 13 | 14 | % Interface between the instrument and the host computer: '1GbE' 15 | interface = '1GbE'; 16 | 17 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 18 | host = 'localhost'; 19 | 20 | % Sweep parameters 21 | start_frequency = 100e6; % [Hz] 22 | stop_frequency = 8400e6; % [Hz] 23 | num_points = 50; % Number of frequency points 24 | 25 | %% Connection to instrument ---------------------------------------------- 26 | 27 | % Close current API sessions 28 | clear ziDAQ 29 | 30 | % Create an API session to the data server 31 | port = 8004; % Data server port to communicate 32 | api_level = 6; % Maximum API level supported by the instrument 33 | ziDAQ('connect', host, port, api_level); 34 | 35 | % Establish a connection between data server and instrument 36 | ziDAQ('connectDevice', device, interface); 37 | 38 | %% Instrument settings --------------------------------------------------- 39 | 40 | % Define all the settings in a cell 41 | device_settings = { 42 | % Adjust the data rate of demodulator 1 43 | ['/' device '/demods/0/rate'], 10e3 44 | % Enable continuous data streaming of demodulator 1 45 | ['/' device '/demods/0/trigger/triggeracq'], 0 46 | % Enable the data transfer from demodulator 1 to data server 47 | ['/' device '/demods/0/enable'], 1 48 | }; 49 | 50 | % Apply all the settings to the device via a transaction 51 | ziDAQ('set', device_settings); 52 | 53 | %% Sweeper module -------------------------------------------------------- 54 | 55 | % Create an instance of the Sweeper Module 56 | sweeper = ziDAQ('sweep'); 57 | 58 | % Assign the instrument to the sweeper object (must be set first) 59 | ziDAQ('set', sweeper, 'device', device); 60 | 61 | % Specify that a multiband sweep of the specified channel and oscillator should be performed 62 | ziDAQ('set', sweeper, 'gridnode', ['/' device '/multiband/sigins0/oscs0']); 63 | 64 | % Set the start and stop values of the sweeping parameter 65 | ziDAQ('set', sweeper, 'start', start_frequency); 66 | ziDAQ('set', sweeper, 'stop', stop_frequency); 67 | 68 | % Set the number of points in the sweep range 69 | ziDAQ('set', sweeper, 'samplecount', num_points); 70 | 71 | % Sequential sweep from start to stop points 72 | ziDAQ('set', sweeper, 'scan', 'sequential'); 73 | 74 | % Linear scale of sweeping parameter (frequency) 75 | ziDAQ('set', sweeper, 'xmapping', 'linear'); 76 | 77 | % Automatic control of demodulation bandwidth 78 | ziDAQ('set', sweeper, 'bandwidthcontrol', 2); 79 | 80 | % Demodulation filter order 81 | ziDAQ('set', sweeper, 'order', 3); 82 | 83 | % Maximum measurement bandwidth [Hz] 84 | ziDAQ('set', sweeper, 'maxbandwidth', 4.0e3); 85 | 86 | % Single-sweep mode 87 | ziDAQ('set', sweeper, 'endless', 0); 88 | 89 | %% Subscription to signal path ------------------------------------------- 90 | 91 | % Subscribe to the signal path of demodulator 1 for acquisition 92 | path = ['/' device '/demods/0/sample']; 93 | ziDAQ('subscribe', sweeper, path); 94 | 95 | %% Run sweeper ----------------------------------------------------------- 96 | 97 | fprintf('\nStart sweeping frequency...\n\n'); 98 | 99 | % Start the sweep 100 | ziDAQ('execute', sweeper); 101 | 102 | sweep_completed = true; 103 | timeout = 30; 104 | t0 = tic; 105 | %while ziDAQ('progress', sweeper) < 1.0 && ~ziDAQ('finished', sweeper) 106 | while ~ziDAQ('finished', sweeper) 107 | pause(1); 108 | fprintf('Progress %0.0f%%\n', ziDAQ('progress', sweeper) * 100); 109 | if toc(t0) > timeout 110 | sweep_completed = false; 111 | break; 112 | end 113 | end 114 | ziDAQ('finish', sweeper); 115 | ziDAQ('unsubscribe', sweeper, '*'); 116 | 117 | if sweep_completed 118 | fprintf('\nSweeper finished within %.1f s.\n\n', toc(t0)); 119 | else 120 | fprintf('\nTimeout: Sweeper could not finish within %.1f s.\n\n', timeout); 121 | end 122 | 123 | % Read out the data acquired by the sweeper 124 | data = ziDAQ('read', sweeper); 125 | 126 | % Destroy the sweeper object 127 | ziDAQ('clear', sweeper); 128 | 129 | %% Disconnection --------------------------------------------------------- 130 | 131 | % Disconnect the device from data server 132 | % ziDAQ('disconnectDevice', device); 133 | 134 | % Destroy the API session 135 | clear ziDAQ 136 | 137 | %% Plotting -------------------------------------------------------------- 138 | 139 | if sweep_completed 140 | 141 | % Extract signal frequency, amplitude and phase 142 | sample = data.(device).demods(1).sample{1,1}; 143 | freq = sample.grid; 144 | amp = sample.r; 145 | phase = sample.phase; 146 | 147 | % Visualization 148 | figure('Name','Bode','NumberTitle','on'); 149 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 150 | subplot(2,1,1) 151 | h = plot(freq * 1e-9, amp); 152 | set(h,'LineWidth',1,'LineStyle','-','Color',[0 0.4470 0.7410]) 153 | xlabel('Frequency (GHz)','fontsize',10,'fontweight','n','color','k'); 154 | ylabel('Amplitude (V)','fontsize',10,'fontweight','n','color','k'); 155 | xlim([start_frequency stop_frequency] * 1e-9); 156 | grid on 157 | title('Frequency Response: Amplitude and Phase') 158 | subplot(2,1,2) 159 | h = plot(freq * 1e-9, (180/pi)*phase); 160 | set(h,'LineWidth',1 ,'LineStyle','-','Color',[0.6350 0.0780 0.1840]) 161 | xlabel('Frequency (GHz)','fontsize',10,'fontweight','n','color','k'); 162 | ylabel('Phase (deg)','fontsize',10,'fontweight','n','color','k'); 163 | xlim([start_frequency stop_frequency] * 1e-9); 164 | grid on 165 | 166 | end 167 | % ------------------------------------------------------------------------ 168 | -------------------------------------------------------------------------------- /shfqa/python/example_qubit_readout_weights.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Measures the integration weights for a qubit readout assuming 8 qubits and using gaussian flat 7 | top pulses. 8 | 9 | Requirements: 10 | * LabOne Version >= 22.02 11 | * Instruments: 12 | 1 x SHFQA or SHFQC Instrument 13 | * Loopback configuration between input and output of channel 0 14 | 15 | Usage: 16 | example_qubit_readout_measurement.py [options] 17 | example_qubit_readout_measurement.py -h | --help 18 | 19 | Arguments: 20 | The ID of the device to run the example with. [device_type: SHFQA | SHFQC] 21 | 22 | Options: 23 | -h --help Show this screen. 24 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 25 | -p --server_port PORT Port number of the data server [default: 8004] 26 | --no-plot Hide plot of the recorded data. 27 | 28 | Returns: 29 | dict integration weights for each qubit 30 | 31 | Raises: 32 | Exception If the specified device does not match the requirements. 33 | RuntimeError If the device is not "discoverable" from the API. 34 | 35 | See the "LabOne Programming Manual" for further help, available: 36 | - On Windows via the Start-Menu: 37 | Programs -> Zurich Instruments -> Documentation 38 | - On Linux in the LabOne .tar.gz archive in the "Documentation" 39 | sub-folder. 40 | """ 41 | 42 | import numpy as np 43 | import zhinst.utils 44 | import zhinst.utils.shfqa as shfqa_utils 45 | import helper_qubit_readout as helper 46 | import helper_commons 47 | 48 | 49 | def run_example( 50 | device_id: str, 51 | server_host: str = "localhost", 52 | server_port: int = 8004, 53 | plot: bool = True, 54 | ): 55 | """run the example.""" 56 | 57 | # connect device 58 | apilevel_example = 6 59 | (daq, _, _) = zhinst.utils.create_api_session( 60 | device_id, apilevel_example, server_host=server_host, server_port=server_port 61 | ) 62 | 63 | # define parameters 64 | channel_index = 0 65 | num_qubits = 8 66 | readout_duration = 600e-9 67 | num_segments = 2 68 | num_averages = 50 69 | num_measurements = num_segments * num_averages 70 | scope_channel = 0 71 | 72 | # configure inputs and outputs 73 | shfqa_utils.configure_channel( 74 | daq, 75 | device_id, 76 | channel_index, 77 | center_frequency=5e9, 78 | input_range=0, 79 | output_range=-5, 80 | mode="readout", 81 | ) 82 | # enable qachannel 83 | path = f"/{device_id}/qachannels/{channel_index}/" 84 | daq.set( 85 | [ 86 | (path + "input/on", 1), 87 | (path + "output/on", 1), 88 | ] 89 | ) 90 | 91 | # configure scope 92 | shfqa_utils.configure_scope( 93 | daq, 94 | device_id, 95 | input_select={scope_channel: f"channel{channel_index}_signal_input"}, 96 | num_samples=int(readout_duration * shfqa_utils.SHFQA_SAMPLING_FREQUENCY), 97 | trigger_input=f"channel{channel_index}_sequencer_monitor0", 98 | num_segments=num_segments, 99 | num_averages=num_averages, 100 | # compensation for the delay between generator output and input of the integration unit 101 | trigger_delay=200e-9, 102 | ) 103 | 104 | # generate and upload waveforms 105 | excitation_pulses = helper_commons.generate_flat_top_gaussian( 106 | frequencies=np.linspace(2e6, 32e6, num_qubits), 107 | pulse_duration=500e-9, 108 | rise_fall_time=10e-9, 109 | sampling_rate=shfqa_utils.SHFQA_SAMPLING_FREQUENCY, 110 | ) 111 | shfqa_utils.write_to_waveform_memory( 112 | daq, device_id, channel_index, waveforms=excitation_pulses 113 | ) 114 | 115 | # configure sequencer 116 | shfqa_utils.configure_sequencer_triggering( 117 | daq, device_id, channel_index, aux_trigger="software_trigger0" 118 | ) 119 | 120 | # run experiment measurement loop 121 | weights = {} 122 | for i in range(num_qubits): 123 | print(f"Measuring qubit {i}.") 124 | 125 | # upload sequencer program 126 | seqc_program = helper.generate_sequencer_program( 127 | num_measurements=num_measurements, 128 | task="dig_trigger_play_single", 129 | waveform_slot=i, 130 | ) 131 | shfqa_utils.load_sequencer_program( 132 | daq, device_id, channel_index, sequencer_program=seqc_program 133 | ) 134 | 135 | # start a measurement 136 | shfqa_utils.enable_scope(daq, device_id, single=1) 137 | shfqa_utils.enable_sequencer(daq, device_id, channel_index, single=1) 138 | # Note: software triggering is used for illustration purposes only. Use a real 139 | # trigger source for actual experiments 140 | shfqa_utils.start_continuous_sw_trigger( 141 | daq, device_id, num_triggers=num_measurements, wait_time=readout_duration 142 | ) 143 | 144 | # get results to calculate weights and plot data 145 | scope_data, *_ = shfqa_utils.get_scope_data(daq, device_id, timeout=5) 146 | 147 | weights[i] = helper.calculate_readout_weights(scope_data[scope_channel]) 148 | 149 | if plot: 150 | helper.plot_scope_data_for_weights( 151 | scope_data[scope_channel], 152 | sampling_rate=shfqa_utils.SHFQA_SAMPLING_FREQUENCY, 153 | ) 154 | helper.plot_readout_weights( 155 | weights[i], sampling_rate=shfqa_utils.SHFQA_SAMPLING_FREQUENCY 156 | ) 157 | 158 | return weights 159 | 160 | 161 | if __name__ == "__main__": 162 | import sys 163 | from pathlib import Path 164 | 165 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 166 | sys.path.insert(0, str(cli_util_path)) 167 | cli_utils = __import__("cli_utils") 168 | cli_utils.run_commandline(run_example, __doc__) 169 | sys.path.remove(str(cli_util_path)) 170 | -------------------------------------------------------------------------------- /ghfli/matlab/example_ghfli_triggered_data_acquisition.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2024 Zurich Instruments AG 3 | % This example demonstrates how to acquire triggered demodulator data using 4 | % the DAQ module for the GHFLI Lock-in Amplifier. 5 | 6 | % Clear and close everything 7 | close all; clear; clc; 8 | 9 | %% User settings --------------------------------------------------------- 10 | 11 | % Serial number of instrument in its rear panel. 12 | device = 'dev10000'; 13 | 14 | % Interface between the instrument and the host computer: '1GbE' 15 | interface = '1GbE'; 16 | 17 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 18 | host = 'localhost'; 19 | 20 | % Number of samples to be measured following a trigger event 21 | burst_length = 256; 22 | 23 | % Number of triggers to be issued 24 | trigger_count = 3; 25 | 26 | %% Connection to instrument ---------------------------------------------- 27 | 28 | % Close current API sessions 29 | clear ziDAQ 30 | 31 | % Create an API session to the data server 32 | port = 8004; % Data server port to communicate 33 | api_level = 6; % Maximum API level supported by the instrument 34 | ziDAQ('connect', host, port, api_level); 35 | 36 | % Establish a connection between data server and instrument 37 | ziDAQ('connectDevice', device, interface); 38 | 39 | %% Instrument settings --------------------------------------------------- 40 | 41 | % Define all the settings in a cell 42 | device_settings = { 43 | % Use software enabled trigger acquisition for the example 44 | ['/' device '/demods/0/trigger/source'], 1024 45 | % Adjust the data rate of demodulator 1 46 | ['/' device '/demods/0/rate'], 2048 47 | % Set the number of samples to be measured following a trigger event 48 | ['/' device '/demods/0/burstlen'], burst_length 49 | % Enable the triggered data acquisition of demodulator 1 50 | ['/' device '/demods/0/trigger/triggeracq'], 1 51 | % Enable data transfer from demodulator 1 to data server 52 | ['/' device '/demods/0/enable'], 1 53 | }; 54 | 55 | % Apply all the settings to the device via a transaction 56 | ziDAQ('set', device_settings); 57 | 58 | % Time difference (s) between two consecutive timestamp ticks 59 | dt_device = ziDAQ('getDouble', ['/' device '/system/properties/timebase']); 60 | 61 | %% DAQ module -------------------------------------------------------- 62 | 63 | % Create an instance of the DAQ Module 64 | daq_module = ziDAQ('dataAcquisitionModule'); 65 | 66 | % Set the device that will be used for the trigger - this parameter must be set. 67 | ziDAQ('set', daq_module, 'device', device); 68 | 69 | % Configure the daq module to look out for bursts coming from the device (triggering is handled by the device) 70 | ziDAQ('set', daq_module, 'type', 'burst_trigger'); 71 | 72 | % No offset for the trigger position 73 | ziDAQ('set', daq_module, 'delay', 0.0); 74 | 75 | % Set grid mode to be 'exact' or 4, meaning no interpolation from the daq module 76 | ziDAQ('set', daq_module, 'grid/mode', 'exact'); 77 | 78 | % Set the grid columns to be equal to the burst length, given that the grid/mode is exact 79 | ziDAQ('set', daq_module, 'grid/cols', burst_length); 80 | 81 | % Set the number of expected triggers to be acquired 82 | ziDAQ('set', daq_module, 'count', trigger_count); 83 | 84 | % Set the DAQ module to trigger on a change of trigger index, i.e. on HW triggers. 85 | ziDAQ('set', daq_module, 'triggernode', ['/' device '/demods/0/sample.trigindex']); 86 | 87 | %% Subscription to signal path ------------------------------------------- 88 | 89 | trigger_signal_path = ['/' device '/demods/0/sample.r']; 90 | ziDAQ('subscribe', daq_module, trigger_signal_path); 91 | 92 | %% Run DAQ module -------------------------------------------------------- 93 | 94 | fprintf('\nStart DAQ module ...\n\n'); 95 | 96 | ziDAQ('execute', daq_module); 97 | 98 | % Start the triggering process 99 | for i = 1:1:trigger_count 100 | % Issue the software trigger 101 | ziDAQ('setInt', ['/' device '/system/swtriggers/0/single'], 1); 102 | fprintf('Trigger no.%i was sent!\n', i); 103 | % Wait 1 second before triggering again 104 | pause(1); 105 | end 106 | fprintf('\n'); 107 | 108 | daq_completed = true; 109 | timeout = 60; 110 | t0 = tic; 111 | while ziDAQ('progress', daq_module) < 1.0 && ~ziDAQ('finished', daq_module) 112 | pause(1); 113 | fprintf('Progress %0.0f%%\n', ziDAQ('progress', daq_module) * 100); 114 | if toc(t0) > timeout 115 | daq_completed = false; 116 | end 117 | end 118 | ziDAQ('finish', daq_module); 119 | ziDAQ('unsubscribe', daq_module, '*'); 120 | 121 | if daq_completed 122 | fprintf('\nDAQ module finished within %.1f s.\n\n', toc(t0)); 123 | else 124 | fprintf('\nTimeout: DAQ module could not finish within %.1f s.\n\n', timeout); 125 | end 126 | 127 | % Read out the data acquired by the daq module 128 | data = ziDAQ('read', daq_module); 129 | 130 | % Destroy the daq module object 131 | ziDAQ('clear', daq_module); 132 | 133 | %% Disconnection --------------------------------------------------------- 134 | 135 | % Disconnect the device from data server 136 | % ziDAQ('disconnectDevice', device); 137 | 138 | % Destroy the API session 139 | clear ziDAQ 140 | 141 | %% Plotting -------------------------------------------------------------- 142 | 143 | if daq_completed 144 | all_samples = data.(device).demods(1).sample_r; 145 | figure('Name','DAQ Trigger Data','NumberTitle','on'); 146 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 147 | for i=1:1:size(all_samples, 2) 148 | sample = all_samples{1, i}; 149 | values = sample.value * 1e6; 150 | timestamps = double(sample.timestamp - sample.timestamp(1,1)) * dt_device; 151 | subplot(size(all_samples, 2), 1, i); 152 | h = plot(timestamps, values); 153 | set(h,'LineWidth',1,'LineStyle','-'); 154 | xlabel('Time (sec)','fontsize',10,'fontweight','n','color','k'); 155 | ylabel('Signal (μV)','fontsize',10,'fontweight','n','color','k'); 156 | end 157 | end 158 | % ------------------------------------------------------------------------ 159 | -------------------------------------------------------------------------------- /shfli/matlab/example_shfli_triggered_data_acquisition.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2024 Zurich Instruments AG 3 | % This example demonstrates how to acquire triggered demodulator data using 4 | % the DAQ module for the SHFLI Lock-in Amplifier. 5 | 6 | % Clear and close everything 7 | close all; clear; clc; 8 | 9 | %% User settings --------------------------------------------------------- 10 | 11 | % Serial number of instrument in its rear panel. 12 | device = 'dev10000'; 13 | 14 | % Interface between the instrument and the host computer: '1GbE' 15 | interface = '1GbE'; 16 | 17 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 18 | host = 'localhost'; 19 | 20 | % Number of samples to be measured following a trigger event 21 | burst_length = 256; 22 | 23 | % Number of triggers to be issued 24 | trigger_count = 3; 25 | 26 | %% Connection to instrument ---------------------------------------------- 27 | 28 | % Close current API sessions 29 | clear ziDAQ 30 | 31 | % Create an API session to the data server 32 | port = 8004; % Data server port to communicate 33 | api_level = 6; % Maximum API level supported by the instrument 34 | ziDAQ('connect', host, port, api_level); 35 | 36 | % Establish a connection between data server and instrument 37 | ziDAQ('connectDevice', device, interface); 38 | 39 | %% Instrument settings --------------------------------------------------- 40 | 41 | % Define all the settings in a cell 42 | device_settings = { 43 | % Use software enabled trigger acquisition for the example 44 | ['/' device '/demods/0/trigger/source'], 1024 45 | % Adjust the data rate of demodulator 1 46 | ['/' device '/demods/0/rate'], 2048 47 | % Set the number of samples to be measured following a trigger event 48 | ['/' device '/demods/0/burstlen'], burst_length 49 | % Enable the triggered data acquisition of demodulator 1 50 | ['/' device '/demods/0/trigger/triggeracq'], 1 51 | % Enable data transfer from demodulator 1 to data server 52 | ['/' device '/demods/0/enable'], 1 53 | }; 54 | 55 | % Apply all the settings to the device via a transaction 56 | ziDAQ('set', device_settings); 57 | 58 | % Time difference (s) between two consecutive timestamp ticks 59 | dt_device = ziDAQ('getDouble', ['/' device '/system/properties/timebase']); 60 | 61 | %% DAQ module -------------------------------------------------------- 62 | 63 | % Create an instance of the DAQ Module 64 | daq_module = ziDAQ('dataAcquisitionModule'); 65 | 66 | % Set the device that will be used for the trigger - this parameter must be set. 67 | ziDAQ('set', daq_module, 'device', device); 68 | 69 | % Configure the daq module to look out for bursts coming from the device (triggering is handled by the device) 70 | ziDAQ('set', daq_module, 'type', 'burst_trigger'); 71 | 72 | % No offset for the trigger position 73 | ziDAQ('set', daq_module, 'delay', 0.0); 74 | 75 | % Set grid mode to be 'exact' or 4, meaning no interpolation from the daq module 76 | ziDAQ('set', daq_module, 'grid/mode', 'exact'); 77 | 78 | % Set the grid columns to be equal to the burst length, given that the grid/mode is exact 79 | ziDAQ('set', daq_module, 'grid/cols', burst_length); 80 | 81 | % Set the number of expected triggers to be acquired 82 | ziDAQ('set', daq_module, 'count', trigger_count); 83 | 84 | % Set the DAQ module to trigger on a change of trigger index, i.e. on HW triggers. 85 | ziDAQ('set', daq_module, 'triggernode', ['/' device '/demods/0/sample.trigindex']); 86 | 87 | %% Subscription to signal path ------------------------------------------- 88 | 89 | trigger_signal_path = ['/' device '/demods/0/sample.r']; 90 | ziDAQ('subscribe', daq_module, trigger_signal_path); 91 | 92 | %% Run DAQ module -------------------------------------------------------- 93 | 94 | fprintf('\nStart DAQ module ...\n\n'); 95 | 96 | ziDAQ('execute', daq_module); 97 | 98 | % Start the triggering process 99 | for i = 1:1:trigger_count 100 | % Issue the software trigger 101 | ziDAQ('setInt', ['/' device '/system/swtriggers/0/single'], 1); 102 | fprintf('Trigger no.%i was sent!\n', i); 103 | % Wait 1 second before triggering again 104 | pause(1); 105 | end 106 | fprintf('\n'); 107 | 108 | daq_completed = true; 109 | timeout = 60; 110 | t0 = tic; 111 | while ziDAQ('progress', daq_module) < 1.0 && ~ziDAQ('finished', daq_module) 112 | pause(1); 113 | fprintf('Progress %0.0f%%\n', ziDAQ('progress', daq_module) * 100); 114 | if toc(t0) > timeout 115 | daq_completed = false; 116 | end 117 | end 118 | ziDAQ('finish', daq_module); 119 | ziDAQ('unsubscribe', daq_module, '*'); 120 | 121 | if daq_completed 122 | fprintf('\nDAQ module finished within %.1f s.\n\n', toc(t0)); 123 | else 124 | fprintf('\nTimeout: DAQ module could not finish within %.1f s.\n\n', timeout); 125 | end 126 | 127 | % Read out the data acquired by the daq module 128 | data = ziDAQ('read', daq_module); 129 | 130 | % Destroy the daq module object 131 | ziDAQ('clear', daq_module); 132 | 133 | %% Disconnection --------------------------------------------------------- 134 | 135 | % Disconnect the device from data server 136 | % ziDAQ('disconnectDevice', device); 137 | 138 | % Destroy the API session 139 | clear ziDAQ 140 | 141 | %% Plotting -------------------------------------------------------------- 142 | 143 | if daq_completed 144 | all_samples = data.(device).demods(1).sample_r; 145 | figure('Name','DAQ Trigger Data','NumberTitle','on'); 146 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 147 | for i=1:1:size(all_samples, 2) 148 | sample = all_samples{1, i}; 149 | values = sample.value * 1e6; 150 | timestamps = double(sample.timestamp - sample.timestamp(1,1)) * dt_device; 151 | subplot(size(all_samples, 2), 1, i); 152 | h = plot(timestamps, values); 153 | set(h,'LineWidth',1,'LineStyle','-'); 154 | xlabel('Time (sec)','fontsize',10,'fontweight','n','color','k'); 155 | ylabel('Signal (μV)','fontsize',10,'fontweight','n','color','k'); 156 | end 157 | end 158 | % ------------------------------------------------------------------------ 159 | -------------------------------------------------------------------------------- /ghfli/matlab/example_ghfli_poll_data.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2023 Zurich Instruments AG 3 | % This example demonstrates how to poll data from a GHFLI demodulator. 4 | 5 | % Clear and close everything 6 | close all; clear; clc; 7 | 8 | %% User settings --------------------------------------------------------- 9 | 10 | % Serial number of instrument in its rear panel. 11 | device = 'dev10000'; 12 | 13 | % Interface between the instrument and the host computer: '1GbE' 14 | interface = '1GbE'; 15 | 16 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 17 | host = 'localhost'; 18 | 19 | % Rate (Sa/s) of data transfer from the instrument to the host computer 20 | data_rate = 2000; 21 | 22 | % Acquisition time duration (s) 23 | measurement_duration = 6; 24 | 25 | %% Connection to instrument ---------------------------------------------- 26 | 27 | % Close current API sessions 28 | clear ziDAQ 29 | 30 | % Create an API session to the data server 31 | port = 8004; % Data server port to communicate 32 | api_level = 6; % Maximum API level supported by the instrument 33 | ziDAQ('connect', host, port, api_level); 34 | 35 | % Establish a connection between data server and instrument 36 | ziDAQ('connectDevice', device, interface); 37 | 38 | %% Instrument settings --------------------------------------------------- 39 | 40 | % Define all the settings in a cell 41 | device_settings = { 42 | % Adjust the data rate of demodulator 1 43 | ['/' device '/demods/0/rate'], data_rate 44 | % Enable continuous data streaming of demodulator 1 45 | ['/' device '/demods/0/trigger/triggeracq'], 0 46 | % Enable the data transfer from demodulator 1 to data server 47 | ['/' device '/demods/0/enable'], 1 48 | }; 49 | 50 | % Apply all the settings to the device via a transaction 51 | ziDAQ('set', device_settings); 52 | 53 | %% Initial variables ----------------------------------------------------- 54 | 55 | % Time difference (s) between two consecutive timestamp tics 56 | dt_device = ziDAQ('getDouble', ['/' device '/system/properties/timebase']); 57 | 58 | % Timeout of the poll loop 59 | timeout = 1.5 * measurement_duration; 60 | 61 | % Time duration of a single poll execution (s) 62 | poll_duration = 1.5; 63 | 64 | % Timeout of a single poll execution (ms) 65 | poll_timeout = 500; 66 | 67 | % Variables to record time and signal quadrature components X and Y 68 | time = []; 69 | X = []; 70 | Y = []; 71 | 72 | % Current timestamp of the instrument 73 | timestamp_initial = double(ziDAQ('getInt', ['/' device '/status/time'])); 74 | 75 | %% Subscription to data path --------------------------------------------- 76 | 77 | % Subscribe to the signal path of demodulator 1 for acquisition 78 | path = ['/' device '/demods/0/sample']; 79 | ziDAQ('subscribe', path); 80 | 81 | %% Poll data ------------------------------------------------------------- 82 | 83 | % Polling data from the signal path 84 | fprintf('\nStart acquisition of data for %.1f s...\n\n', measurement_duration); 85 | 86 | % Run the poll loop 87 | measured_sofar = 0; 88 | t0 = tic; 89 | while measured_sofar < measurement_duration 90 | data = ziDAQ('poll', poll_duration, poll_timeout); 91 | if ~isempty(data) 92 | x = []; 93 | y = []; 94 | bursts = [data.(device).demods(1).sample.vector(:).segments]; 95 | x = [bursts(:).x]; 96 | y = [bursts(:).y]; 97 | signal_length = length(x); 98 | dt = double(bursts(1).dt); 99 | timestamp = double(bursts(1).timestamp); 100 | initial_time = (double(bursts(1).timestamp) - timestamp_initial) * dt_device; 101 | time_interval = initial_time + (0:1:(signal_length-1)) * dt * dt_device; 102 | time = [time time_interval]; 103 | X = [X x]; 104 | Y = [Y y]; 105 | measured_sofar = time(end) - time(1); 106 | end 107 | elapsed_time = toc(t0); 108 | if elapsed_time > timeout 109 | fprintf('\nTimeout: Data acquisition of %.1f s could not be finished within %.1f s.\n\n', measurement_duration, elapsed_time); 110 | break; 111 | end 112 | fprintf('Elapsed time: %.2f s.\n', elapsed_time); 113 | fprintf('So far acquisition of %.2f s out of %.1f s is done.\n', measured_sofar, measurement_duration); 114 | if measured_sofar >= measurement_duration 115 | fprintf('\nAcquisition is complete.\n\n'); 116 | end 117 | end 118 | 119 | %% Unsubscription -------------------------------------------------------- 120 | 121 | % Unsubscribe from all signal paths 122 | ziDAQ('unsubscribe', '*'); 123 | 124 | %% Disconnection --------------------------------------------------------- 125 | 126 | % Disconnect the device from data server 127 | % ziDAQ('disconnectDevice', device); 128 | 129 | % Destroy the API session 130 | clear ziDAQ 131 | 132 | %% Plotting -------------------------------------------------------------- 133 | 134 | % Plot the amplitude and phase of the measured signal 135 | if ~isempty(time) 136 | plot_amp_phase(time,X,Y); 137 | end 138 | 139 | function plot_amp_phase(t,x,y) 140 | 141 | % Adjust the time axis to start at origin 142 | t = t - t(1); 143 | 144 | % Convertion from quadrature components to polar components 145 | r = abs(x + 1i*y); 146 | phase = atan2d(y,x); 147 | 148 | % Visualization 149 | figure('Name','Demodulation','NumberTitle','on'); 150 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 151 | subplot(2,1,1) 152 | h = plot(t,r); 153 | set(h,'LineWidth',1,'LineStyle','-','Color',[0 0.4470 0.7410]) 154 | xlabel('Time (s)','fontsize',10,'fontweight','n','color','k'); 155 | ylabel('Amplitude (V)','fontsize',10,'fontweight','n','color','k'); 156 | grid on 157 | title('Signal: Amplitude and Phase') 158 | subplot(2,1,2) 159 | h = plot(t,phase); 160 | set(h,'LineWidth',1 ,'LineStyle','-','Color',[0.6350 0.0780 0.1840]) 161 | xlabel('Time (s)','fontsize',10,'fontweight','n','color','k'); 162 | ylabel('Phase (deg)','fontsize',10,'fontweight','n','color','k'); 163 | grid on 164 | 165 | end 166 | % ------------------------------------------------------------------------ 167 | -------------------------------------------------------------------------------- /shfli/matlab/example_shfli_poll_data.m: -------------------------------------------------------------------------------- 1 | %% Description ----------------------------------------------------------- 2 | % Copyright 2023 Zurich Instruments AG 3 | % This example demonstrates how to poll data from an SHFLI demodulator. 4 | 5 | % Clear and close everything 6 | close all; clear; clc; 7 | 8 | %% User settings --------------------------------------------------------- 9 | 10 | % Serial number of instrument in its rear panel. 11 | device = 'dev10000'; 12 | 13 | % Interface between the instrument and the host computer: '1GbE' 14 | interface = '1GbE'; 15 | 16 | % IP address of LabOne data server host, e.g., 'localhost' or '169.254.1.2' 17 | host = 'localhost'; 18 | 19 | % Rate (Sa/s) of data transfer from the instrument to the host computer 20 | data_rate = 2000; 21 | 22 | % Acquisition time duration (s) 23 | measurement_duration = 6; 24 | 25 | %% Connection to instrument ---------------------------------------------- 26 | 27 | % Close current API sessions 28 | clear ziDAQ 29 | 30 | % Create an API session to the data server 31 | port = 8004; % Data server port to communicate 32 | api_level = 6; % Maximum API level supported by the instrument 33 | ziDAQ('connect', host, port, api_level); 34 | 35 | % Establish a connection between data server and instrument 36 | ziDAQ('connectDevice', device, interface); 37 | 38 | %% Instrument settings --------------------------------------------------- 39 | 40 | % Define all the settings in a cell 41 | device_settings = { 42 | % Adjust the data rate of demodulator 1 43 | ['/' device '/demods/0/rate'], data_rate 44 | % Enable continuous data streaming of demodulator 1 45 | ['/' device '/demods/0/trigger/triggeracq'], 0 46 | % Enable the data transfer from demodulator 1 to data server 47 | ['/' device '/demods/0/enable'], 1 48 | }; 49 | 50 | % Apply all the settings to the device via a transaction 51 | ziDAQ('set', device_settings); 52 | 53 | %% Initial variables ----------------------------------------------------- 54 | 55 | % Time difference (s) between two consecutive timestamp tics 56 | dt_device = ziDAQ('getDouble', ['/' device '/system/properties/timebase']); 57 | 58 | % Timeout of the poll loop 59 | timeout = 1.5 * measurement_duration; 60 | 61 | % Time duration of a single poll execution (s) 62 | poll_duration = 1.5; 63 | 64 | % Timeout of a single poll execution (ms) 65 | poll_timeout = 500; 66 | 67 | % Variables to record time and signal quadrature components X and Y 68 | time = []; 69 | X = []; 70 | Y = []; 71 | 72 | % Current timestamp of the instrument 73 | timestamp_initial = double(ziDAQ('getInt', ['/' device '/status/time'])); 74 | 75 | %% Subscription to data path --------------------------------------------- 76 | 77 | % Subscribe to the signal path of demodulator 1 for acquisition 78 | path = ['/' device '/demods/0/sample']; 79 | ziDAQ('subscribe', path); 80 | 81 | %% Poll data ------------------------------------------------------------- 82 | 83 | % Polling data from the signal path 84 | fprintf('\nStart acquisition of data for %.1f s...\n\n', measurement_duration); 85 | 86 | % Run the poll loop 87 | measured_sofar = 0; 88 | t0 = tic; 89 | while measured_sofar < measurement_duration 90 | data = ziDAQ('poll', poll_duration, poll_timeout); 91 | if ~isempty(data) 92 | x = []; 93 | y = []; 94 | bursts = [data.(device).demods(1).sample.vector(:).segments]; 95 | x = [bursts(:).x]; 96 | y = [bursts(:).y]; 97 | signal_length = length(x); 98 | dt = double(bursts(1).dt); 99 | timestamp = double(bursts(1).timestamp); 100 | initial_time = (double(bursts(1).timestamp) - timestamp_initial) * dt_device; 101 | time_interval = initial_time + (0:1:(signal_length-1)) * dt * dt_device; 102 | time = [time time_interval]; 103 | X = [X x]; 104 | Y = [Y y]; 105 | measured_sofar = time(end) - time(1); 106 | end 107 | elapsed_time = toc(t0); 108 | if elapsed_time > timeout 109 | fprintf('\nTimeout: Data acquisition of %.1f s could not be finished within %.1f s.\n\n', measurement_duration, elapsed_time); 110 | break; 111 | end 112 | fprintf('Elapsed time: %.2f s.\n', elapsed_time); 113 | fprintf('So far acquisition of %.2f s out of %.1f s is done.\n', measured_sofar, measurement_duration); 114 | if measured_sofar >= measurement_duration 115 | fprintf('\nAcquisition is complete.\n\n'); 116 | end 117 | end 118 | 119 | %% Unsubscription -------------------------------------------------------- 120 | 121 | % Unsubscribe from all signal paths 122 | ziDAQ('unsubscribe', '*'); 123 | 124 | %% Disconnection --------------------------------------------------------- 125 | 126 | % Disconnect the device from data server 127 | % ziDAQ('disconnectDevice', device); 128 | 129 | % Destroy the API session 130 | clear ziDAQ 131 | 132 | %% Plotting -------------------------------------------------------------- 133 | 134 | % Plot the amplitude and phase of the measured signal 135 | if ~isempty(time) 136 | plot_amp_phase(time,X,Y); 137 | end 138 | 139 | function plot_amp_phase(t,x,y) 140 | 141 | % Adjust the time axis to start at origin 142 | t = t - t(1); 143 | 144 | % Convertion from quadrature components to polar components 145 | r = abs(x + 1i*y); 146 | phase = atan2d(y,x); 147 | 148 | % Visualization 149 | figure('Name','Demodulation','NumberTitle','on'); 150 | set(gca,'FontSize',12,'LineWidth',2,'Color',[1 1 1],'Box','on'); 151 | subplot(2,1,1) 152 | h = plot(t,r); 153 | set(h,'LineWidth',1,'LineStyle','-','Color',[0 0.4470 0.7410]) 154 | xlabel('Time (s)','fontsize',10,'fontweight','n','color','k'); 155 | ylabel('Amplitude (V)','fontsize',10,'fontweight','n','color','k'); 156 | grid on 157 | title('Signal: Amplitude and Phase') 158 | subplot(2,1,2) 159 | h = plot(t,phase); 160 | set(h,'LineWidth',1 ,'LineStyle','-','Color',[0.6350 0.0780 0.1840]) 161 | xlabel('Time (s)','fontsize',10,'fontweight','n','color','k'); 162 | ylabel('Phase (deg)','fontsize',10,'fontweight','n','color','k'); 163 | grid on 164 | 165 | end 166 | % ------------------------------------------------------------------------ 167 | -------------------------------------------------------------------------------- /hf2-mf-uhf/python/example_connect_config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Demonstrate how to create an API session by connecting to a Data Server in order 7 | to communicate with a Zurich Instruments device. 8 | Connect to a Zurich Instruments device via the Data Server, 9 | configure some settings on the instrument, obtain a single demodulator 10 | sample via getSample(), calculate and add its RMS amplitude as a field to 11 | the ``sample`` dictionary and return that dictionary. 12 | 13 | Note: 14 | This is intended to be a simple example demonstrating how to connect to a 15 | Zurich Instruments device from Python. In most cases, data acquisition 16 | should use either ziDAQServer's poll() method or an instance of the 17 | ziDAQRecorder class, not the getSample() method. 18 | 19 | Requirements: 20 | * LabOne Version >= 20.02 21 | * Instruments: 22 | 1 x Instrument with demodulators 23 | * Signal output 1 conected to signal input 1 with a BNC cable. 24 | 25 | Usage: 26 | example_connect_config.py [options] 27 | example_connect_config.py -h | --help 28 | 29 | Arguments: 30 | The ID of the device [device_type: .*LI|.*IA|.*IS] 31 | 32 | Options: 33 | -h --help Show this screen. 34 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 35 | -p --server_port PORT Port number of the data server [default: None] 36 | --hf2 Flag if the used device is an HF2 instrument. (Since the HF2 uses 37 | a different data server and support only API level 1 38 | it requires minor tweaking) [default = False] 39 | -a --amplitude AMPLITUDE The amplitude to set on the signal output. [default: 0.100] 40 | 41 | Raises: 42 | Exception If the specified devices do not match the requirements. 43 | RuntimeError If the devices is not "discoverable" from the API. 44 | 45 | See the LabOne Programming Manual for further help: 46 | https://docs.zhinst.com/labone_programming_manual/ 47 | """ 48 | 49 | import time 50 | import numpy as np 51 | import zhinst.utils 52 | 53 | 54 | def run_example( 55 | device_id: str, 56 | server_host: str = "localhost", 57 | server_port: int = None, 58 | hf2: bool = False, 59 | amplitude: float = 0.100, 60 | ): 61 | """run the example.""" 62 | 63 | apilevel_example = 1 if hf2 else 6 # The API level supported by this example. 64 | if not server_port: 65 | server_port = 8005 if hf2 else 8004 66 | # Call a zhinst utility function that returns: 67 | # - an API session `daq` in order to communicate with devices via the data server. 68 | # - the device ID string that specifies the device branch in the server's node hierarchy. 69 | # - the device's discovery properties. 70 | (daq, device, props) = zhinst.utils.create_api_session( 71 | device_id, apilevel_example, server_host=server_host, server_port=server_port 72 | ) 73 | 74 | # Create a base configuration: Disable all available outputs, awgs, demods, scopes,... 75 | zhinst.utils.disable_everything(daq, device) 76 | 77 | # Now configure the instrument for this experiment. The following channels 78 | # and indices work on all device configurations. The values below may be 79 | # changed if the instrument has multiple input/output channels and/or either 80 | # the Multifrequency or Multidemodulator options installed. 81 | out_channel = 0 82 | out_mixer_channel = zhinst.utils.default_output_mixer_channel(props) 83 | in_channel = 0 84 | demod_index = 0 85 | osc_index = 0 86 | demod_rate = 10e3 87 | time_constant = 1e-6 88 | exp_setting = [ 89 | ["/%s/sigins/%d/ac" % (device, in_channel), 0], 90 | ["/%s/sigins/%d/range" % (device, in_channel), 2 * amplitude], 91 | ["/%s/demods/%d/enable" % (device, demod_index), 1], 92 | ["/%s/demods/%d/rate" % (device, demod_index), demod_rate], 93 | ["/%s/demods/%d/adcselect" % (device, demod_index), in_channel], 94 | ["/%s/demods/%d/order" % (device, demod_index), 4], 95 | ["/%s/demods/%d/timeconstant" % (device, demod_index), time_constant], 96 | ["/%s/demods/%d/oscselect" % (device, demod_index), osc_index], 97 | ["/%s/demods/%d/harmonic" % (device, demod_index), 1], 98 | ["/%s/oscs/%d/freq" % (device, osc_index), 400e3], 99 | ["/%s/sigouts/%d/on" % (device, out_channel), 1], 100 | ["/%s/sigouts/%d/enables/%d" % (device, out_channel, out_mixer_channel), 1], 101 | ["/%s/sigouts/%d/range" % (device, out_channel), 1], 102 | [ 103 | "/%s/sigouts/%d/amplitudes/%d" % (device, out_channel, out_mixer_channel), 104 | amplitude, 105 | ], 106 | ] 107 | daq.set(exp_setting) 108 | 109 | # Wait for the demodulator filter to settle. 110 | time.sleep(10 * time_constant) 111 | 112 | # Perform a global synchronisation between the device and the data server: 113 | # Ensure that the settings have taken effect on the device before issuing 114 | # the getSample() command. Note: the sync() must be issued after waiting for 115 | # the demodulator filter to settle above. 116 | daq.sync() 117 | 118 | # Obtain one demodulator sample via ziDAQServer's low-level getSample() 119 | # method - for extended data acquisition it's preferable to use 120 | # ziDAQServer's poll() method or the ziDAQRecorder class. 121 | sample = daq.getSample("/%s/demods/%d/sample" % (device, demod_index)) 122 | # Calculate the demodulator's magnitude and phase and add them to the sample 123 | # dict. 124 | sample["R"] = np.abs(sample["x"] + 1j * sample["y"]) 125 | sample["phi"] = np.angle(sample["x"] + 1j * sample["y"]) 126 | print(f"Measured RMS amplitude is {sample['R'][0]:.3e} V.") 127 | 128 | 129 | if __name__ == "__main__": 130 | import sys 131 | from pathlib import Path 132 | 133 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 134 | sys.path.insert(0, str(cli_util_path)) 135 | cli_utils = __import__("cli_utils") 136 | cli_utils.run_commandline(run_example, __doc__) 137 | sys.path.remove(str(cli_util_path)) 138 | -------------------------------------------------------------------------------- /uhfqa/python/example_monitor.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Run a basic test of the input averager. 7 | 8 | The example plays gaussian waveforms on each output using the AWG and runs 9 | the monitor to record them. 10 | 11 | Requirements: 12 | * LabOne Version >= 21.02 13 | * Instruments: 14 | 1 x UHFQA Instrumemt. 15 | * Signal output 1 connected to signal input 1 with a BNC cable. 16 | * Signal output 2 connected to signal input 2 with a BNC cable. 17 | 18 | Usage: 19 | example_monitor.py [options] 20 | example_monitor.py -h | --help 21 | 22 | Arguments: 23 | The ID of the device to run the example with. [device_type: UHFQA] 24 | 25 | Options: 26 | -h --help Show this screen. 27 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 28 | -p --server_port PORT Port number of the data server [default: 8004] 29 | --no-plot Hide plot of the recorded data. 30 | -v --vector_length LENGTH Length of the output waveform. [default: 4000] 31 | -l --monitor_length LENGTH Number of monitor samples to obtain. [default: 4000] 32 | -a --num_averages VAL Number of averages per measurement. [default: 256] 33 | 34 | Returns: 35 | data Measurement result. (dict) 36 | 37 | Raises: 38 | Exception If the specified device does not match the requirements. 39 | RuntimeError If the device is not "discoverable" from the API. 40 | 41 | See the LabOne Programming Manual for further help: 42 | https://docs.zhinst.com/labone_programming_manual/ 43 | """ 44 | 45 | import time 46 | import textwrap 47 | import zhinst.utils 48 | import matplotlib.pyplot as plt 49 | 50 | import common_uhfqa 51 | 52 | 53 | def run_example( 54 | device_id: str, 55 | server_host: str = "localhost", 56 | server_port: int = 8004, 57 | vector_length: int = 4000, 58 | monitor_length: int = 4000, 59 | num_averages: int = 256, 60 | plot: bool = True, 61 | ): 62 | """run the example.""" 63 | 64 | apilevel_example = 6 # The API level supported by this example. 65 | # Call a zhinst utility function that returns: 66 | # - an API session `daq` in order to communicate with devices via the data server. 67 | # - the device ID string that specifies the device branch in the server's node hierarchy. 68 | # - the device's discovery properties. 69 | daq, device, _ = zhinst.utils.create_api_session( 70 | device_id, apilevel_example, server_host=server_host, server_port=server_port 71 | ) 72 | 73 | # Perform initialization for UHFQA examples 74 | common_uhfqa.initialize_device(daq, device) 75 | 76 | # Configure AWG to output gaussian pulses on output 1 and 2 77 | awg_program = textwrap.dedent( 78 | """\ 79 | const LENGTH = ${LENGTH}; 80 | wave w = gauss(LENGTH, LENGTH/2, LENGTH/8); 81 | 82 | var loop_cnt = getUserReg(0); 83 | var wait_time = 0; 84 | 85 | repeat(loop_cnt) { 86 | setTrigger(0); 87 | playWave(w, -w); 88 | wait(50); 89 | setTrigger(AWG_MONITOR_TRIGGER); 90 | setTrigger(0); 91 | waitWave(); 92 | wait(1000); 93 | } 94 | """ 95 | ).replace("${LENGTH}", f"{vector_length:d}") 96 | 97 | # Provide number of averages in user register 98 | daq.set(f"/{device:s}/awgs/0/userregs/0", num_averages) 99 | 100 | # Create an instance of the AWG module 101 | awgModule = daq.awgModule() 102 | awgModule.set("device", device) 103 | awgModule.set("index", 0) 104 | awgModule.execute() 105 | 106 | # Transfer the AWG sequence program. Compilation starts automatically. 107 | awgModule.set("compiler/sourcestring", awg_program) 108 | while awgModule.getInt("compiler/status") == -1: 109 | time.sleep(0.1) 110 | 111 | # Ensure that compilation was successful 112 | assert awgModule.getInt("compiler/status") != 1 113 | 114 | daq.set( 115 | [ 116 | # Enable outputs 117 | (f"/{device:s}/sigouts/*/on", 1), 118 | # Setup monitor 119 | (f"/{device:s}/qas/0/monitor/averages", num_averages), 120 | (f"/{device:s}/qas/0/monitor/length", monitor_length), 121 | ] 122 | ) 123 | 124 | monitor_length = daq.getInt(f"/{device:s}/qas/0/monitor/length") 125 | 126 | # Now we're ready for readout. Enable monitor and start acquisition. 127 | daq.set( 128 | [ 129 | (f"/{device:s}/qas/0/monitor/reset", 1), 130 | (f"/{device:s}/qas/0/monitor/enable", 1), 131 | ] 132 | ) 133 | daq.sync() 134 | 135 | # Subscribe to monitor waves 136 | paths = [] 137 | for channel in range(2): 138 | path = f"/{device:s}/qas/0/monitor/inputs/{channel:d}/wave" 139 | paths.append(path) 140 | daq.subscribe(paths) 141 | 142 | # Arm the device 143 | daq.set( 144 | [ 145 | (f"/{device:s}/awgs/0/single", 1), 146 | (f"/{device:s}/awgs/0/enable", 1), 147 | ] 148 | ) 149 | 150 | # Perform acquisition 151 | print("Acquiring data...") 152 | data = common_uhfqa.acquisition_poll(daq, paths, monitor_length) 153 | print("Done.") 154 | 155 | # Stop monitor 156 | daq.unsubscribe(paths) 157 | daq.set(f"/{device:s}/qas/0/monitor/enable", 0) 158 | 159 | if plot: 160 | fig, axes = plt.subplots(figsize=(12, 4)) 161 | axes.set_title(f"Input averager results after {num_averages:d} measurements") 162 | axes.set_ylabel("Amplitude (a.u.)") 163 | axes.set_xlabel("Sample (#)") 164 | for path, samples in data.items(): 165 | axes.plot(samples, label=f"Readout {path}") 166 | plt.legend(loc="best") 167 | fig.set_tight_layout(True) 168 | plt.show() 169 | 170 | return data 171 | 172 | 173 | if __name__ == "__main__": 174 | import sys 175 | from pathlib import Path 176 | 177 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 178 | sys.path.insert(0, str(cli_util_path)) 179 | cli_utils = __import__("cli_utils") 180 | cli_utils.run_commandline(run_example, __doc__) 181 | sys.path.remove(str(cli_util_path)) 182 | -------------------------------------------------------------------------------- /mf/python/example_poll_impedance.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Zurich Instruments AG 2 | 3 | """ 4 | Zurich Instruments LabOne Python API Example 5 | 6 | Demonstrate how to obtain impedance data using ziDAQServer's blocking 7 | (synchronous) poll() command. 8 | Connect to the device specified by device_id and obtain 9 | impedance data using ziDAQServer's blocking (synchronous) poll() command. 10 | 11 | Requirements: 12 | * LabOne Version >= 20.02 13 | * Instruments: 14 | 1 x Instrument with IA option 15 | * Connect Impedance Testfixture and attach a 1kOhm resistor 16 | 17 | Usage: 18 | example_autoranging_impedance.py [options] 19 | example_autoranging_impedance.py -h | --help 20 | 21 | Arguments: 22 | The ID of the device [device_type: MF*(IA)] 23 | 24 | Options: 25 | -h --help Show this screen. 26 | -s --server_host IP Hostname or IP address of the dataserver [default: localhost] 27 | -p --server_port PORT Port number of the data server [default: 8004] 28 | --no-plot Hide plot of the recorded data. 29 | 30 | Returns: 31 | sample The impedance sample dictionary as returned by poll. 32 | 33 | Raises: 34 | Exception If the specified devices do not match the requirements. 35 | RuntimeError If the devices is not "discoverable" from the API. 36 | 37 | See the LabOne Programming Manual for further help: 38 | https://docs.zhinst.com/labone_programming_manual/ 39 | """ 40 | 41 | import time 42 | import zhinst.utils 43 | import matplotlib.pyplot as plt 44 | import numpy as np 45 | 46 | import example_autoranging_impedance 47 | 48 | 49 | def run_example( 50 | device_id: str, 51 | server_host: str = "localhost", 52 | server_port: int = 8004, 53 | plot: bool = True, 54 | ): 55 | """run the example.""" 56 | 57 | apilevel_example = 6 # The API level supported by this example. 58 | # Call a zhinst utility function that returns: 59 | # - an API session `daq` in order to communicate with devices via the data server. 60 | # - the device ID string that specifies the device branch in the server's node hierarchy. 61 | # - the device's discovery properties. 62 | (daq, device, _) = zhinst.utils.create_api_session( 63 | device_id, apilevel_example, server_host=server_host, server_port=server_port 64 | ) 65 | 66 | # Create a base configuration: Disable all available outputs, awgs, demods, scopes,... 67 | zhinst.utils.disable_everything(daq, device) 68 | 69 | # We use the auto-range example to perform some basic device configuration 70 | # and wait until signal input ranges have been configured by the device. 71 | example_autoranging_impedance.run_example(device) 72 | 73 | # Subscribe to the impedance sample node path. 74 | imp_index = 0 75 | path = "/%s/imps/%d/sample" % (device, imp_index) 76 | daq.subscribe(path) 77 | 78 | # Sleep for demonstration purposes: Allow data to accumulate in the data 79 | # server's buffers for one second: poll() will not only return the data 80 | # accumulated during the specified poll_length, but also for data 81 | # accumulated since the subscribe() or the previous poll. 82 | sleep_length = 1.0 83 | # For demonstration only: We could, for example, be processing the data 84 | # returned from a previous poll(). 85 | time.sleep(sleep_length) 86 | 87 | # Poll the subscribed data from the data server. Poll will block and record 88 | # for poll_length seconds. 89 | poll_length = 0.1 # [s] 90 | poll_timeout = 500 # [ms] 91 | poll_flags = 0 92 | poll_return_flat_dict = True 93 | data = daq.poll(poll_length, poll_timeout, poll_flags, poll_return_flat_dict) 94 | 95 | # Unsubscribe from all paths. 96 | daq.unsubscribe("*") 97 | 98 | # Check the dictionary returned is non-empty 99 | assert ( 100 | data 101 | ), "poll() returned an empty data dictionary, did you subscribe to any paths?" 102 | 103 | # The data returned is a dictionary of dictionaries that reflects the node's path. 104 | # Note, the data could be empty if no data had arrived, e.g., if the imps 105 | # were disabled or had transfer rate 0. 106 | assert path in data, "The data dictionary returned by poll has no key `%s`." % path 107 | 108 | # Access the impedance sample using the node's path. For more information 109 | # see the data structure documentation for ZIImpedanceSample in the LabOne 110 | # Programming Manual. 111 | impedance_sample = data[path] 112 | 113 | # Get the sampling rate of the device's ADCs, the device clockbase in order 114 | # to convert the sample's timestamps to seconds. 115 | clockbase = float(daq.getInt("/%s/clockbase" % device)) 116 | 117 | dt_seconds = ( 118 | impedance_sample["timestamp"][-1] - impedance_sample["timestamp"][0] 119 | ) / clockbase 120 | num_samples = len(impedance_sample["timestamp"]) 121 | print( 122 | f"poll() returned {num_samples} samples of impedance data spanning {dt_seconds:.3f} \ 123 | seconds." 124 | ) 125 | print(f"Average measured resitance: {np.mean(impedance_sample['param0'])} Ohm.") 126 | print(f"Average measured capacitance: {np.mean(impedance_sample['param1'])} F.") 127 | 128 | if plot: 129 | # Convert timestamps from ticks to seconds via clockbase. 130 | t = ( 131 | impedance_sample["timestamp"] - impedance_sample["timestamp"][0] 132 | ) / clockbase 133 | 134 | plt.close("all") 135 | # Create plot 136 | _, axes = plt.subplots(2, sharex=True) 137 | axes[0].plot(t, impedance_sample["param0"]) 138 | axes[0].set_title("Impedance Parameters") 139 | axes[0].grid(True) 140 | axes[0].set_ylabel(r"Resistance ($\Omega$)") 141 | axes[0].autoscale(enable=True, axis="x", tight=True) 142 | 143 | axes[1].plot(t, impedance_sample["param1"]) 144 | axes[1].grid(True) 145 | axes[1].set_ylabel(r"Capacitance (F)") 146 | axes[1].set_xlabel("Time (s)") 147 | axes[1].autoscale(enable=True, axis="x", tight=True) 148 | 149 | plt.draw() 150 | plt.show() 151 | 152 | return data 153 | 154 | 155 | if __name__ == "__main__": 156 | import sys 157 | from pathlib import Path 158 | 159 | cli_util_path = Path(__file__).resolve().parent / "../../utils/python" 160 | sys.path.insert(0, str(cli_util_path)) 161 | cli_utils = __import__("cli_utils") 162 | cli_utils.run_commandline(run_example, __doc__) 163 | sys.path.remove(str(cli_util_path)) 164 | --------------------------------------------------------------------------------