├── 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]}{tag}>")
75 | for cell in cells[1:]:
76 | self.f.write(f"<{tag} style='text-align:center'>{cell}{tag}>")
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 |
--------------------------------------------------------------------------------