zhinst / zhinst-qcodes Goto Github PK
View Code? Open in Web Editor NEWQCoDeS drivers for Zurich Instruments devices
License: MIT License
QCoDeS drivers for Zurich Instruments devices
License: MIT License
I was trying to set an amplitude on the MFLI, which I assume would be mfli1.sigouts[0].amplitudes[0].value()
. I got an error that there is no attribute value
. When I checked the snapshot, there is no parameters on 0th channel.
> mfli1.sigouts[0].amplitudes[0].snapshot()
{'functions': {},
'submodules': {},
'parameters': {},
'__class__': 'zhinst.qcodes.qcodes_adaptions.ZINode',
'name': 'mfli1_sigouts0_amplitudes0'}
However, I could set the amplitude with mfli1.sigouts[0].amplitudes[1].value(0.05)
> mfli1.sigouts[0].amplitudes[0].snapshot()
Is it intentional that it's not zero-based index?
Using the daq module on a MFLI, I have several questions regarding the workflow:
session = Session("localhost")
device = session.connect_device("devXXXX")
daq = session.modules.daq
daq.subscribe(device.demods[0].sample.x)
daq.subscribe(device.demods[0].sample.y)
With zhinst-qcodes however, daq.subscribe
takes a ZIParameter, which I cannot seem to get:
session = ZISession("localhost")
device = session.connect_device("devXXXX")
daq = session.modules.daq
daq.subscribe(device.demods[0].sample.x)
# AttributeError: 'ZIParameter' object has no attribute 'x'
daq.subscribe(device.demods[0].sample.tk_node.x)
# Tries to subscribe to /devXXXX/demods/0/sample.x.tk_node, which ends up not working
daq._tk_object.subscribe(device.demods[0].sample.tk_node.x)
# This works
What is the preferred way of subscribing to those nodes? What is with .avg and the like?
execute()
and read()
functions? Is there a more elegant way than calling daq._tk_object.execute()
and daq._tk_object.read()
?Thank you and best regards
With the new release of zhinst-core zhinst-qcodes is no longer marked as type checked. This causes type checking failures when running type checking on qcodes (of the aliases shipped in qcodes.instrument_drivers.zhinst
)
Normally typechecking is marked by shipping a py.typed
file. I guess that zhinst-core used to ship that file at the toplevel module but no longer does. An alternative fix could be for zhinst-qcodes to ship the file at its toplevel module
The failures that we observe are.
pyright 1.1.332, node v[20](https://github.com/QCoDeS/Qcodes/actions/runs/6704453962/job/18255153080#step:7:21).8.1, pyright-action 1.7.1
/home/runner/runners/2.311.0/externals/node20/bin/node /opt/hostedtoolcache/pyright/1.1.332/x64/package/index.js --outputjson
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/hdawg.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/hf2.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/mfli.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/pqsc.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/shfqa.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/shfsg.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/uhfli.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
/home/runner/work/Qcodes/Qcodes/src/qcodes/instrument_drivers/zurich_instruments/uhfqa.py:8:10 - error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
Error: Stub file not found for "zhinst.qcodes" (reportMissingTypeStubs)
8 errors, 0 warnings, 0 informations
Error: 8 errors
See an example here microsoft/Qcodes#5477 where the version of zhinst-core is bumped causing typechecking that was passing to fail
Dear ZI qcodes developers,
If for whatever reason someone disables demodulator (something like this in mfli: mfli.demods.demods0.enable(0)), then tries to get or set demods parameters like sample, the behavior is that the driver waits for for some time and returns timeout error.
Also, when this timeout error happens, the next parameter you try to get will return a RuntimeError: ('ZIAPIServerException with status code: 32782. Command failed internally, ...)
I think this can be nicely handled with a user friendly error message to let know that the demodulator is disabled and ask the user to enable it before trying to query the instrument for related parameters.
Hi,
Qcodes Measurement needs validators for parameters in the measurement. If there is no validator, qcodes interprets it as numeric and perform measurement. This is not problematic until if the output of a parameter is complex. Then measurement won’t run and throws error.
We face this when we want to get value of mfli.demods.demods0.sample in our measurement (The other signals that I checked were not problematic). I tried to dig a bit on this and found out that the unit of sample is ‘dependent’. So, I am not sure if this sample always returns complex or it could also return float.
At the moment, our users have a work around and that is to validate this parameter before running a measurement, something like this:
mfli.demods.demods0.sample.vals = qcodes.utils.validators.ComplexNumbers()
But, I am looking for implementing a validator inside your driver for this sample parameter, if I know it always returns complex or if it is not, we should validate it based on the return value of the parameter. Or you may suggest something else to solve this issue in the driver level.
Thanks
Hello,
First of all, thank you for providing a new driver for the HF2LI product!
An issue happened to me when I tried it on my machine. I followed the example provided in zhinst-qcodes/examples/hf2.md
from zhinst.qcodes import HF2
device = HF2("DEVXXXX", "localhost")
and I got this error :
Node /DEV847/STATS/PHYSICAL/1V2 could not be added as parameter
Parameter name must be a valid identifier got 1v2 which is not. Parameter names cannot start with a number and must not contain spaces or special characters
Node /DEV847/STATS/PHYSICAL/1V8 could not be added as parameter
Parameter name must be a valid identifier got 1v8 which is not. Parameter names cannot start with a number and must not contain spaces or special characters
Node /DEV847/STATS/PHYSICAL/2V5 could not be added as parameter
Parameter name must be a valid identifier got 2v5 which is not. Parameter names cannot start with a number and must not contain spaces or special characters
Node /DEV847/STATS/PHYSICAL/3V3 could not be added as parameter
Parameter name must be a valid identifier got 3v3 which is not. Parameter names cannot start with a number and must not contain spaces or special characters
Node /DEV847/STATS/PHYSICAL/5V0 could not be added as parameter
Parameter name must be a valid identifier got 5v0 which is not. Parameter names cannot start with a number and must not contain spaces or special characters
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Input In [2], in <module>
1 from zhinst.qcodes import HF2
----> 3 device = HF2("DEV847", "localhost")
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\device_creator.py:109, in ZIDeviceHF2.__new__(self, serial, host, port, interface, name, raw, new_session)
97 def __new__(
98 self,
99 serial: str,
(...)
106 new_session: bool = False
107 ):
108 session = ZISession(host, port, hf2=True, new_session=new_session)
--> 109 return session.connect_device(serial, interface=interface, name=name, raw=raw)
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\session.py:563, in Session.connect_device(self, serial, interface, name, raw)
561 self._devices.update_device_properties(serial, name, raw)
562 self._tk_object.connect_device(serial, interface=interface)
--> 563 return self._devices[serial]
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\session.py:47, in Devices.__getitem__(self, key)
45 tk_device = self._tk_devices[key]
46 name, raw = self._default_properties.get(key, (None, False))
---> 47 self._devices[key] = ZIDevices.DEVICE_CLASS_BY_MODEL.get(
48 tk_device.__class__.__name__, ZIDevices.ZIBaseInstrument
49 )(tk_device, self._session, name=name, raw=raw)
50 return self._devices[key]
51 raise KeyError(key)
File ~\anaconda3\envs\qcodes\lib\site-packages\qcodes\instrument\base.py:508, in AbstractInstrumentMeta.__call__(cls, *args, **kwargs)
503 def __call__(cls, *args: Any, **kwargs: Any) -> Any:
504 """
505 Overloads `type.__call__` to add code that runs only if __init__ completes
506 successfully.
507 """
--> 508 new_inst = super().__call__(*args, **kwargs)
509 is_abstract = new_inst._is_abstract()
510 if is_abstract:
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\driver\devices\base.py:44, in ZIBaseInstrument.__init__(self, tk_object, session, name, raw)
42 if not raw:
43 self._init_additional_nodes()
---> 44 init_nodetree(self, self._tk_object.root, self._snapshot_cache)
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\qcodes_adaptions.py:590, in init_nodetree(layer, nodetree, snapshot_cache, blacklist)
588 qcodes_list = tk_node_to_qcodes_list(node)
589 name = qcodes_list[-1]
--> 590 parent = _get_submodule(layer, qcodes_list[:-1], snapshot_cache)
591 do_snapshot = (
592 "Stream" not in info.get("Properties")
593 and "ZIVector" not in info.get("Type")
594 and "Read" in info.get("Properties")
595 and not any(x in node.raw_tree for x in snapshot_blacklist)
596 )
597 parent.add_parameter(
598 parameter_class=ZIParameter,
599 name=name,
(...)
613 snapshot_cache=snapshot_cache,
614 )
File ~\anaconda3\envs\qcodes\lib\site-packages\zhinst\qcodes\qcodes_adaptions.py:557, in _get_submodule(layer, parents, snapshot_cache)
550 module = ZINode(
551 current_layer,
552 node,
553 zi_node="/".join(parents[:i] + [name, str(number)]),
554 snapshot_cache=snapshot_cache,
555 )
556 current_layer.submodules[name].append(module)
--> 557 current_layer = current_layer.submodules[name][number]
558 elif node not in current_layer.submodules:
559 module = ZINode(
560 current_layer,
561 node,
562 zi_node="/".join(parents[: i + 1]),
563 snapshot_cache=snapshot_cache,
564 )
File ~\anaconda3\envs\qcodes\lib\site-packages\qcodes\instrument\channel.py:281, in ChannelTuple.__getitem__(self, i)
272 elif isinstance(i, tuple):
273 return type(self)(
274 self._parent,
275 self._name,
(...)
279 snapshotable=self._snapshotable,
280 )
--> 281 return self._channels[i]
IndexError: list index out of range
I am far from being an expert in this, but it seems clear that it can't go to the DevXXXX/STATS/PHYSICAL/*v* because of their name. I tried to see if i could enter these nodes with PuTTY (as it is recommended in the HF2Li User manual Ch5.2) and it didn't appreciate the format either. It seems like in order to go to the /DEVXXX/STATS/PHYSICAL/V node, one need to enter /DEVXXX/STATS/PHYSICAL/0;1;2;3;4 instead.
Let me know if you need anything more I can give,
Elric
The documentation here mentions a list of nodes that have changed but I don't see that anywhere in that page. The page here does not mention changes to sigout and demods
Specifically I don't see the following documented
sigout[0].amplitudes0...3
have changed into a ChannelList with a single parameter value sigout[0].amplitudes[0...3].value
The first 2 changes are clearly improvements but it would be nice if they had been documented.
The 3th one is more problematic since it now breaks our ability to directly measure parameters using qcodes.
e.g. the following no longer works
output_no_sync = do1d(freqparam, 50, 300, 10, 2, mfli2.demods[0].sample)
For now we have our resorted to work around this with a complex_sample parameter that retains the old behavior added in a subclass
I am trying to run repetitions for averaging on the DAQ module for reduced noise in measurements however the averaging is not being applied. Setting repetitions will increase the measurement time as expected but the data being fed back is not actually being averaged compared to a run with repetitions set to 1.
I suspect the issue is that the grid operations mode is set to replace instead of averaging as shown in the screenshot from the GUI. However, this parameter node does not seem to be available in the qcodes driver? Is there anywhere else this parameter is set from qcodes python terminal?
This is running with version 0.3.4 as pulled by pip install.
QCoDes will drop Python3.7 support presumably in version 0.37
. Act according to that.
Source: microsoft/Qcodes#3889
There is a bug that prevents using the new API to establish a connection to the UHFLI.
session.devices.connected() returns ['dev2454'], which is the ID of our instrument. When we then try
session.devices['dev2454']
or equivalently
session.connect_device('dev2454')
we get an error due to not having the AWG option installed on our instrument:
session.devices['dev2454']
The AWG option is not installed.
Traceback (most recent call last):
File "", line 1, in
File "/home/triton5/.local/lib/python3.9/site-packages/zhinst/qcodes/session.py", line 47, in getitem
self._devices[key] = ZIDevices.DEVICE_CLASS_BY_MODEL.get(
File "/home/triton5/.local/lib/python3.9/site-packages/qcodes/instrument/base.py", line 508, in call
new_inst = super().call(*args, **kwargs)
File "/home/triton5/.local/lib/python3.9/site-packages/zhinst/qcodes/driver/devices/base.py", line 43, in init
self._init_additional_nodes()
File "/home/triton5/.local/lib/python3.9/site-packages/zhinst/qcodes/driver/devices/uhfli.py", line 203, in _init_additional_nodes
if self._tk_object.awgs:
File "/home/triton5/.local/lib/python3.9/site-packages/zhinst/toolkit/driver/devices/uhfli.py", line 33, in awgs
for i in range(len(self["awgs"]))
File "/home/triton5/.local/lib/python3.9/site-packages/zhinst/toolkit/nodetree/node.py", line 406, in len
raise TypeError(f"Node {self.node_info.path} is not a list")
TypeError: Node /dev2454/awgs is not a list
There is no way that I can find to flag that the instrument doesn't have the AWG option or something like that.
Dear ZI qcodes developers,
While using the zhinst-qcodes package, I came across a problem when I tried to access the input impedance of trigger input 1 (see example). I think it is the same for all settings under node /devXXX/triggers/in/*
. They are not accessible within the zhinst-qcodes package. For example trying to access node '/devXXX/triggers/in/0/imp50' results in a syntax error as shown in the example below:
import qcodes as qc
import zhinst.qcodes as ziqc
uhfli = ziqc.UHFLI(name="uhfli", serial="dev2547")
uhfli.triggers.in.in0.imp50()
File "C:\Users\G-GRE-~1\AppData\Local\Temp/ipykernel_13576/2615439366.py", line 1
uhfli.triggers.in.in0.imp50()
^
SyntaxError: invalid syntax
I assume that uhfli.triggers.in.in0.imp50()
should be the good way to query the input impedance of trigger input 1 since the API log shows me ziDAQ('setInt', '/dev2547/triggers/in/0/imp50', 1)
when setting it to 50 Ohm.
Would it be an option to map the node keyword in
to input
or similar to avoid in
?
Or is there another way to access these setting with the zhinst-qcodes package?
Hi all,
I was previously using the old qcodes to connect to my HF2LI as
from qcodes.instrument_drivers.ZI.ZIUHFLI import ZIUHFLI
ZIUHFLI(name='u1', device_ID='DEV405')
and it worked great.
I was obtaining the following print
Discovered device `dev405`: HF2LI with options MF, WEB.
Creating an API session for device `dev405` on `127.0.0.1`, `8005` with apilevel `1`.
I recently updated my workstation to the new qcodes and I got a deprecated message while using that code
QCoDeSDeprecationWarning: The class <ZIUHFLI> is deprecated, because There is a new UHFLI driver from Zurich Instruments. Use "instrument_drivers.zurich_instruments.uhfli.UHFLI" as an alternative.
issue_deprecation_warning(f'{t} <{n}>', reason, alternative)
I so used the suggested code and I simply can't connect to the HF2LI anymore.
from qcodes.instrument_drivers.zurich_instruments.uhfli import UHFLI
UHFLI(name='uhf4',
serial='dev405',
interface='USB',
port=8005,
api=1)
gives me
Successfully connected to data server at localhost:8005 api version: 1
Successfully connected to device DEV405 on interface USB
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-19-33866b347b0b> in <module>
----> 1 UHFLI(name='uhf4',
2 serial='dev405',
3 interface='USB',
4 port=8005,
5 api=1)
~\Anaconda3\lib\site-packages\zhinst\qcodes\uhfli.py in __init__(self, name, serial, interface, host, port, api, **kwargs)
383 **kwargs,
384 ) -> None:
--> 385 super().__init__(name, "uhfli", serial, interface, host, port, api, **kwargs)
386 submodules = self.nodetree_dict.keys()
387 # initialize submodules from nodetree with blacklist
~\Anaconda3\lib\site-packages\zhinst\qcodes\base.py in __init__(self, name, device_type, serial, interface, host, port, api, **kwargs)
81 f"Device type {device_type} is currently not supported in ziQCoDeS. Supported types are {supported_types}"
82 )
---> 83 self._connect()
84
85 def _connect(self) -> None:
~\Anaconda3\lib\site-packages\zhinst\qcodes\uhfli.py in _connect(self)
409 )
410 self._controller.setup()
--> 411 self._controller.connect_device(nodetree=False)
412 self.connect_message()
413 self._get_nodetree_dict()
~\Anaconda3\lib\site-packages\zhinst\toolkit\control\drivers\uhfli.py in connect_device(self, nodetree)
69
70 """
---> 71 super().connect_device(nodetree=nodetree)
72 self._get_streamingnodes()
73 if "AWG" in self._options:
~\Anaconda3\lib\site-packages\zhinst\toolkit\control\drivers\base\base.py in connect_device(self, nodetree)
110 if nodetree:
111 self._nodetree = NodeTree(self)
--> 112 self._options = self._get("/features/options").split("\n")
113 self._init_settings()
114
~\Anaconda3\lib\site-packages\zhinst\toolkit\control\drivers\base\base.py in _get(self, command, valueonly)
207 """
208 self._check_connected()
--> 209 return self._controller.get(command, valueonly=valueonly)
210
211 def _get_nodetree(self, prefix: str, **kwargs) -> Dict:
~\Anaconda3\lib\site-packages\zhinst\toolkit\control\connection.py in get(self, command, valueonly)
487 else:
488 data = self._connection.get(node_string, settingsonly=False, flat=True)
--> 489 data = self._get_value_from_dict(data)
490 if valueonly:
491 if len(data) > 1:
~\Anaconda3\lib\site-packages\zhinst\toolkit\control\connection.py in _get_value_from_dict(self, data)
541 if isinstance(data_dict, list):
542 data_dict = data_dict[0]
--> 543 if "value" in data_dict.keys():
544 new_data[key] = data_dict["value"][0]
545 if "vector" in data_dict.keys():
AttributeError: 'str' object has no attribute 'keys'
If someone could give me some clue, that would be nice!
Hi there,
I would like to use the 1x8 channelgrouping of the HDAWG8, so I can run programs from all 8 outputs synchronized.
The zhinst.qcodes HDAWG driver has 4 qcodes InstrumentChannels of class zhinst.qcodes.control.drivers.hdawg.AWG, regardless of channelgrouping, matching the 4 physical FPGAs I imagine.
If I switch to 1x8 channelgrouping, some methods work fine on the 4 InstrumentChannels (e.g. outputs). The run() method executes, but does not do anything (perhaps the set_sequence_params method as well) . The compile method fails with the following error:
ERROR: hdawg.awgs[3].compile()
hdawg-awg-3: Sequencer status: ELF upload failed!
Traceback (most recent call last):
File "D:\users\hw_sw_integration\projects\low-level-software\untitled1.py", line 27, in <module>
hdawg.awgs[3].compile()
File "D:\users\hw_sw_integration\venv-3.9\lib\site-packages\zhinst\qcodes\control\drivers\hdawg.py", line 256, in compile
self._awg.compile()
File "D:\users\hw_sw_integration\venv-3.9\lib\site-packages\zhinst\toolkit\control\drivers\base\awg.py", line 303, in compile
_logger.error(
File "D:\users\hw_sw_integration\venv-3.9\lib\site-packages\zhinst\toolkit\interface\interface.py", line 193, in error
raise LoggerModule.ToolkitError(msg)
ToolkitError: hdawg-awg-3: Sequencer status: ELF upload failed!
The following script will reproduce the error:
from zhinst.qcodes import HDAWG
hdawg = HDAWG("hdawg", "DEV8049")
hdawg.system.awg.channelgrouping(0) # 4x2 channelgrouping
hdawg.awgs[3].set_sequence_params(sequence_type="Custom", program="")
hdawg.awgs[3].compile()
hdawg.awgs[3].run()
hdawg.awgs[3].output1("on")
hdawg.awgs[3].output1("off")
hdawg.awgs[3].stop()
hdawg.system.awg.channelgrouping(2) # 1x8 channelgrouping
hdawg.awgs[3].set_sequence_params(sequence_type="Custom", program="")
hdawg.awgs[3].compile() # <-- gives error
hdawg.awgs[3].run()
hdawg.awgs[3].output1("on")
hdawg.awgs[3].output1("off")
hdawg.awgs[3].stop()
If I take the LabOne interface as guidance, it makes perfect sense that I cannot do this, because there is only 1 AWG sequencer available. From the point of the qcodes driver, I would expect to be able to use the 4 InstrumentChannels, regardless of channelgrouping. I could switch back and forth between AWG channels, but it's not so pretty. For example, the following works:
hdawg.system.awg.channelgrouping(2)
hdawg.awgs[0].set_sequence_params(sequence_type="Custom", program="")
hdawg.awgs[0].compile()
hdawg.awgs[0].run()
hdawg.awgs[3].output1("on")
hdawg.awgs[3].output1("off")
hdawg.awgs[0].stop()
Would it be possible to have hdawg.awgs[0:4] point to the corresponding AWG sequencer, depending on the channelgrouping?
For compile, I am thinking this would mean changing self._index
in this line to point to the sequencer:
https://github.com/zhinst/zhinst-toolkit/blob/bdeabc0d0e382246f82c9fe758631d43f54ada65/src/zhinst/toolkit/control/drivers/base/awg.py#L262
For run, this would mean changing self._index
here:
https://github.com/zhinst/zhinst-toolkit/blob/bdeabc0d0e382246f82c9fe758631d43f54ada65/src/zhinst/toolkit/control/drivers/hdawg.py#L342
And I think this would involve changes for all other functionality in the zhinst.toolkit.control.drivers.hdawg.AWG class that uses f"awgs/{self._index}/"
Please let me know what you think.
Sincerely, Harold
With the most recent version of qcodes the definition of Instrument._name
is removed. However, all of the connect
methods in the different ZI drivers use this attribute to grab the instrument name (rather than Instrument.name
). This now leads to an AttributeError as it does not exist. These calls to self._name
should all be replaced by self.name
.
The example here https://docs.zhinst.com/zhinst-qcodes/en/latest/refactoring/index.html seems out of date since
from zhinst.qcodes import Session
results in an ImportError.
I guess the code should read
from zhinst.qcodes import ZISession
The last release indicated here on github is 0.3.0 (https://github.com/zhinst/zhinst-qcodes/releases/tag/v0.3), whereas there is version 0.4.0 available on pypi.org (https://pypi.org/project/zhinst-qcodes/). Where can I find the release notes/changelog? Thanks for keeping the documentation up to date.
The UHF series has scope support but is blacklisted in the constructor see.
Perhaps this is done for a specific reason. It would be really helpfull to provide an example how to initialize the scope module using zhinst-qcodes without having to modify the sources.
from zhinst.qcodes import ZISession
import time
session = ZISession("localhost")
session.connect_device('dev4493')
mfli = session.devices['dev4493']
mfli.oscs[0].freq(11)
time.sleep(0.1)
mfli.oscs[0].freq(100)
print(mfli.oscs[0].freq())
time.sleep(0.1)
print(mfli.oscs[0].freq())
results in the following output
11.000000057492798
99.99999996068709
E.g. if you set a value of a parameter and get it right away it will typically not get the latest value but return the previous value.
Sleeping for 0.1 sec or so before getting seems to result in the correct value being returned.
I would expect set on any value to be blocking unless explicitly stated otherwise so this behavior is surprising.
zhinst 22.2.29711
zhinst-deviceutils 0.1
zhinst-qcodes 0.3.4
zhinst-toolkit 0.3.3
Tested with both
labone 20.07.23.25
and
22.02.29711 with the same result
Consider the difference between creating an MFLI via the session object and manually.
from zhinst.qcodes import ZISession
from zhinst.qcodes import MFLI
session = ZISession("localhost")
session.connect_device('dev4493')
mfli = session.devices['dev4493']
isinstance(mfli, MFLI)
False
mfli.close()
mfli = MFLI(name="mfli1", serial="dev4493", host="localhost")
isinstance(mfli, MFLI)
True
mfli.close()
The instrument produced by the session api is of type ZIBaseInstrument and not MFLI as expected
zhinst 22.2.29711
zhinst-deviceutils 0.1
zhinst-qcodes 0.3.4
zhinst-toolkit 0.3.3
In general I find the session based api suboptimal to use with QCoDeS since
Dear Zurich Instruments,
I am not able to import zhinst-qcodes.
This is the computer set-up:
Anaconda
Python 3.10.6
Windows 10
The minimal code to reproduce it for me is:
import zhinst.qcodes
Do you know how I can fix this?
All other package import work, including zhinst.
The traceback given is:
ImportError Traceback (most recent call last)
Cell In [5], line 1
----> 1 import zhinst.qcodes
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\qcodes\__init__.py:1
----> 1 from zhinst.qcodes.control.drivers import *
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\qcodes\control\drivers\__init__.py:1
----> 1 from .hdawg import HDAWG
2 from .uhfqa import UHFQA
3 from .uhfli import UHFLI
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\qcodes\control\drivers\hdawg.py:1
----> 1 from .base import ZIBaseInstrument
2 import zhinst.toolkit as tk
3 from zhinst.toolkit.control.drivers.hdawg import AWG as HDAWG_AWG
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\qcodes\control\drivers\base\__init__.py:1
----> 1 from .base import ZIBaseInstrument
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\qcodes\control\drivers\base\base.py:7
5 from qcodes.instrument.channel import ChannelList, InstrumentChannel
6 from qcodes.utils.validators import ComplexNumbers
----> 7 import zhinst.toolkit as tk
8 from typing import List, Dict
11 class ZIQcodesException(Exception):
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\toolkit\__init__.py:17
1 # Copyright (C) 2020 Zurich Instruments
2 #
3 # This software may be modified and distributed under the terms
4 # of the MIT license. See the LICENSE file for details.
5 """The Zurich Instruments Toolkit (zhinst-toolkit)
6
7 This package is a collection of Python tools for high level device
(...)
14 Labber. It comes in the form of a package compatible with Python 3.6+.
15 """
---> 17 from zhinst.toolkit.control.drivers import (
18 BaseInstrument,
19 HDAWG,
20 UHFQA,
21 UHFLI,
22 MFLI,
23 PQSC,
24 SHFQA,
25 SHFSG,
26 )
27 from zhinst.toolkit.interface import DeviceTypes
28 from zhinst.toolkit.control.multi_device_connection import MultiDeviceConnection
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\toolkit\control\drivers\__init__.py:10
1 # Copyright (C) 2020 Zurich Instruments
2 #
3 # This software may be modified and distributed under the terms
4 # of the MIT license. See the LICENSE file for details.
5 """The Zurich Instruments Toolkit (zhinst-toolkit) Drivers
6
7 This package is a collection of high level controllers for Zurich
8 Instruments devices.
9 """
---> 10 from .base import BaseInstrument
11 from .hdawg import HDAWG
12 from .uhfqa import UHFQA
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\toolkit\control\drivers\base\__init__.py:1
----> 1 from .awg import AWGCore
2 from .scope import Scope
3 from .shf_qachannel import SHFQAChannel
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\toolkit\control\drivers\base\awg.py:14
12 from zhinst.toolkit.helpers import SequenceProgram, Waveform, SequenceType, TriggerMode
13 from zhinst.toolkit.interface.interface import DeviceTypes
---> 14 from .base import BaseInstrument
15 from zhinst.toolkit.interface import LoggerModule
16 from ...parsers import Parse
File ~\Anaconda3\envs\SSNL\lib\site-packages\zhinst\toolkit\control\drivers\base\base.py:15
13 from typing import Dict
14 import time
---> 15 import zhinst.ziPython as zi
17 from zhinst.toolkit.control.connection import DeviceConnection, ZIConnection
18 from zhinst.toolkit.control.node_tree import NodeTree
ImportError: DLL load failed while importing ziPython: The specified module could not be found.
Dear ZI,
We recently got report from our labs that with the latest qcodes and toolkit driver 0.2.x, there are random phase change in the two-MFLI setup. So, we think that there is some kind of a sync problem.
As we didn't have this problem report with the older driver (sync was more stable), we tried multiple tests to provide you with the minimal attached example notebook:
ZI MDS sync issue.zip
We tried to describe our findings in the notebook, but feel free to ask any question if something is not clear in the notebook.
For now, we limited zi drivers to 0.1.x, and asked our users to not update to the latest firmware.
Thank you.
LabOne offers two ways of changing a not value. Asynchronous (default) is the fast way. Synchronous (deep=True) blocks until the device has acknowledged the value and there for ensures that the value has been processed by the device before the python execution continuous.
The device acknowledges the value is has processed. Since this value can differ from the input value (e.g. floating point arithmetic, limits ...) it can be important to know this value as an end user. LabOne and toolkit there for returns this value.
The LabOne QCoDeS driver however does not.
The problem is that QCoDeS by design does not support returning a value for a set command.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.