Session¶
In this chapter, we provide a brief overview of the functionality of the
Session
class. A Session is the fundamental way to interact with
physical and emulated devices within the LabOne Q framework. This class
represents a single client session to a data server, which manages the
communication between the user PC and the instruments in the QCCS
system. For a more detailed description of the architecture, we refer
the reader to the LabOne user
manual.
In the context of LabOne Q, the Session
can be defined using a
DeviceSetup
and takes care of verifying the availability of the instruments
described by this class.
As the main endpoint for the user interaction with the QCCS, a session
object holds information about the physical wiring of the devices and
their calibrations properties,
information about the experiment definition that can be run on the
devices, and the results of executed experiments.
## define Session object
session = Session(device_setup=device_setup)
## connect the Session
session.connect()
Using this class it is possible to run experiments, compile experiments without running them, adjust the level of logs produced during execution, and much more.
## compile an experiment without running it
session.compile(exp)
## set log level to debug
import logging
session.log_level = logging.DEBUG
## run the experiment
session.run(exp)
A complete list of the functionalities of this class can be found in the API documentation.
Emulation Mode¶
A Session
can be run in emulation mode
by connecting with the corresponding do_emulation=True
option.
No actual connection to the physical devices is attempted in this case.
## connect the Session in emulation mode)
session.connect(do_emulation=False)
Note, that the compiler still produces code consistent with the
requirements of the devices within that Session
object.
The emulation mode of the Session
therefore serves to test the compilation and -to
some extent- execution of experiments without using the actual instruments.
A successfully executed experiment will produce arrays with axes corresponding to the
sweeps, averaging and data acquisition settings of the experiment.
These arrays contain complex mock-up data for debugging purposes
A + j*B
A
of this mock-up data corresponds to 42
plus the index of the
integrator unit assigned to the particular channel of the emulated QA device where the
experimental signal is mapped to. This means that for typical settings where signals
from multiple qubit readouts are multiplexed into one channel, this index will
correspond to the qubit index.
The complex component B
indicates the index in the data array.
Reusing an Active Session¶
The Session
object needs a few seconds to establish the initial communication to the instruments connected to the dataserver.
Repeatedly initializing new Session
objects can therefore lead to a significant time overhead and should be avoided.
Note
An initialized and connected Session
object is intended to compile and execute all experiments of a given workflow.
Instead, an active Session
object can compile and run multiple different experiments.
## run the first experiment (compilation happens implicitly)
session.run(exp1)
## compile the second experiment
compiled_exp2 = session.compile(exp2)
## run the second experiment
session.run(compiled_exp2)
Zurich Instruments Toolkit¶
As the fundamental class for the instrument interface, a Session
can
be used to control individual devices and node values. This is performed
using the
zhinst.toolkit
to
address a specific device contained in the Session
.
Danger
Using Toolkit functions is not possible if the Session
was created in emulation mode
, as it is impossible to address physical
nodes without connecting to an instrument.
Warning
- When LabOne Q controls devices by running an experiment via
session.run()
, never use subscribe/poll overzhinst.toolkit
(neither in the main script before/aftersession.run()
, nor in the near-time callbacks) - When working solely with the
zhinst.toolkit
and only getting the initial connection via LabOne Q session, use subscribe/poll as you need it.
To address a device, we can use its uid as defined in the
descriptor
,
and then using a toolkit command to change a specific node.
## connect to the session
session.connect()
## change the amplitude of channel 1 to 1 V
session.devices["device_hdawg"].awgs[0].outputs[0].amplitude(1)
Note
A device can also be addressed using its serial number instead of its
uid. Using this descriptor,
for example, we could substitute device_hdawg
with DEV8000
to
produce an identical result.
Using this functionality, a Session
can be used to change, or even
sweep, a node of a device inside an Experiment
definition, as
described in the chapter Callback Functions and 3rd-Party
Devices.
Note that this can only be done in near-time.