Timeline Module¶
The Timeline Module provides an interface for configuring and executing time-defined measurement sequences on supported Zurich Instruments devices. It allows users to combine waveform playback, triggers, demodulator acquisition, controller actions, repetitions, and parameter sweeps within a single schedule composed of nested time sections. The module supports both graphical configuration in LabOne User Interface (UI) and programmatic access through the LabOne API, enabling reproducible continuous-wave and pulsed experiments with deterministic timing and sample-accurate synchronization.
Info
The Timeline Module corresponds to the Timeline Tab in the LabOne UI. The behavior of the Timeline Tab can therefore be directly mapped to the LabOne API.
Important
The Timeline Module is also the interface for the Arbitrary Waveform Generator (AWG) Option for the Zurich Instruments Lock-in Amplifiers. In the current LabOne version the Timeline Module requires the AWG Option to be installed on the instrument.
Core Concepts¶
An experiment configured with the Timeline Module is structured hierarchically: it consists of a block that contains sections. Sections can include operations at the section level, as well as signal lines. Each signal line contains a list of operations that execute sequentially.
The LabOne UI allows building the experiments visually. The resulting programmatic representation in JSON format is generated automatically, requiring no manual coding.
Blocks¶
The block is the root of the experiment. It holds the number of repetitions defined by iterations and an ordered sequence of sections to execute. When iterations is greater than one, the entire sequence of sections is repeated that many times from the beginning.
Sections¶
A section is a time container with a defined start and end. It bounds the operations on its signal line within a precise temporal frame, making it straightforward to position pulses and measurements relative to each other. The section's duration is determined by the length of its signal line.
Sections can contain either a signal line with sequential operations or nested sections, but not both at once. Nesting allows composing compound time structures where an outer section sets the overall temporal frame and inner sections divide it into sub-intervals.
Measurement configuration¶
In addition to the signal lines, sections allow measurement operations that start at the beginning of the section with a duration that matches the section's duration.
Valid measurements include scope0, demod0, demod1, ..., pid0, pid1, ... with their corresponding data transfer rates. For accurate signal alignments, the experiment duration must be commensurable with these data rates. As a result, the module automatically extends the final section duration when a measurements entry is present, to align with the corresponding data grids.
Each measurement trigger initiates data transfer on the configured channels. The most convenient way to acquire demodulator and PID data is to subscribe to their corresponding node paths (see Signal Subscription) and call read() at the end of the timeline execution. It is also possible to use the standalone DAQ Module for the same purpose. For scope measurements, use the Scope Module to acquire the data.
Operations¶
Operations are placed in a signal line and executed sequentially. Common operations include:
Delay— wait for a fixed duration before the next operation.Pulse— plays a waveform on a signal generator output (sigout*lines). Requires the AWG Option.
AWG Option and Pulses¶
Arbitrary waveform playback is executed by the Pulse operation added to a signal output line, which requires the AWG Option. The pulse can be selected from a library of predefined waveforms or supplied as a custom waveform. Predefined waveforms include rectangular, Gaussian, DRAG, frequency chirp, cosine, and several others; the full list with corresponding waveform parameters is available in the Timeline Tab of the LabOne UI.
Custom waveforms are available by uploading in the LabOne UI or providing I and Q sample arrays. Values must be in the range [−1, 1]. For a defined number of samples, the waveform duration is calculated based on the data rate of the instrument's signal output.
Modulation¶
When modulation is enabled, the AWG output is mixed with a carrier generated by two of the internal sine wave generators of the lock-in amplifier for I/Q modulation. The generator pair is fixed per signal output: generators 3 and 4 are used for signal output 1, and generators 7 and 8 are used for signal output 2. When modulation is disabled, the AWG output is sent directly to the signal output without oscillator mixing. Once the Timeline Module starts its execution, it takes control of these generators and releases them once it finishes. To configure the oscillator, phase shift, and harmonic settings, use the associated device nodes (e.g. /dev..../generators/n/oscselect) for the signal generators before executing the Timeline Module. The modulation frequency can be configured using the selected oscillator's node /dev..../oscs/n/freq.
LabOne UI–API Hybrid Workflow¶
The recommended approach for scripting Timeline Module experiments is to design the experiment visually in the LabOne Timeline Tab and then export the complete setup as API code using the built-in API Log. This eliminates the need to write the Timeline Module experiment program manually.
Step 1 — Design in the LabOne Timeline Tab¶
Open the Timeline Tab in the LabOne UI for your connected device and build the experiment graphically:
- Configure the block repetitions and add sections within it.
- Add signal lines to each section, place operations on them, and configure the operation parameters in the settings side panel.
- Configure instrument settings (signal outputs, demodulators, scope) in the relevant UI tabs.
- Verify the timing and data using the Viewer and execute the experiment.
Step 2 — Export via the API Log¶
The LabOne UI records every action as a LabOne API command. Open the API Log from the bottom of the screen. It captures the complete setup in one place, including:
- Device node settings — all instrument configuration applied in the UI (signal output levels, demodulator rates, scope trigger settings, and so on).
- Timeline Module node settings — the module parameters (
device,historylength, and so on). - Timeline Module sequence — the full experiment definition written to the
sequence/sourcestringnode, encoding every section, block, and operation exactly as configured in the LabOne UI.
Info
The exported code does not include the device connection step because the API Log does not record it. See the Getting Started Tutorial for how to connect to the instrument from the API. See also How to Use the LabOne UI Logging Feature for a detailed walkthrough of the API Log, including how to change the output language (Python, MATLAB, .NET).
Step 3 — Run via the API¶
Paste the exported device node settings and Timeline Module sequence from the API Log into your script, then execute it. A minimal execution loop is shown below for each supported API.
from zhinst.toolkit import Session
session = Session("localhost")
device = session.connect_device("DEV2345")
# --- paste exported device node settings here ---
tlm = session.modules.timeline
tlm.device(device)
tlm.sequence.sourcestring(timeline_json_string)
tlm.execute()
import time
while not tlm.finished():
time.sleep(0.1)
print(f"Progress: {tlm.progress() * 100:.0f}%")
data = tlm.read()
from zhinst.core import ziDAQServer
daq = ziDAQServer("localhost", 8004, 6)
daq.connectDevice("DEV2345", "1GbE")
# --- paste exported device node settings here ---
tlm = daq.timelineModule()
tlm.set("device", "DEV2345")
tlm.set("sequence/sourcestring", timeline_json_string)
tlm.execute()
import time
while not tlm.finished():
time.sleep(0.1)
print(f"Progress: {tlm.progress()[0] * 100:.0f}%")
data = tlm.read()
ZIConnection conn = nullptr;
handleError(conn, ziAPIInit(&conn));
handleError(conn, ziAPIConnectEx(conn, "localhost", 8004, ZI_API_VERSION_6, nullptr));
handleError(conn, ziAPIConnectDevice(conn, "DEV2345", "1GbE", nullptr));
// --- paste exported device node settings here ---
ZIModuleHandle tlm;
handleError(conn, ziAPIModCreate(conn, &tlm, "timelineModule"));
handleError(conn, ziAPIModSetString(conn, tlm, "/DEVICE", "DEV2345"));
handleError(conn, ziAPIModSetString(conn, tlm, "/SEQUENCE/SOURCESTRING", timeline_json_string));
handleError(conn, ziAPIModExecute(conn, tlm));
int64_t finished = 0;
while (!finished) {
handleError(conn, ziAPIModFinished(conn, tlm, &finished));
usleep(100000);
}
ziDAQ('connect', 'localhost', 8004, 6);
ziDAQ('connectDevice', 'DEV2345', '1GbE');
% --- paste exported device node settings here ---
tlm = ziDAQ('timelineModule');
ziDAQ('setString', tlm, '/DEVICE', 'DEV2345');
ziDAQ('setString', tlm, '/SEQUENCE/SOURCESTRING', timeline_json_string);
ziDAQ('execute', tlm);
while ~ziDAQ('finished', tlm)
pause(0.1);
fprintf('Progress: %.0f%%\n', ziDAQ('progress', tlm) * 100);
end
data = ziDAQ('read', tlm);
using zhinst;
ziDotNET daq = new ziDotNET();
daq.init("localhost", 8004, (ZIAPIVersion_enum)6);
daq.connectDevice("DEV2345", "1GbE", "");
// --- paste exported device node settings here ---
ziModule tlm = daq.timelineModule();
tlm.setString("/DEVICE", "DEV2345");
tlm.setString("/SEQUENCE/SOURCESTRING", timeline_json_string);
tlm.execute();
while (!tlm.finished()) {
System.Threading.Thread.Sleep(100);
}
ZIModuleEventDictionary data = tlm.read();
The read() call returns the acquired data indexed by subscribed node path. Each entry contains the time-stamped samples recorded during the experiment (demodulator, scope, or PID data depending on the configured measurements).
To interrupt a running experiment, call finish() on the module. To re-run the same experiment without re-uploading the sequence, call execute() again.
Note
Uploading a new Timeline Sequence while the module is running does not interrupt the current execution. The new definition takes effect on the next call to execute().
Node Documentation¶
This section describes all the nodes in the Timeline Module node tree organized by branch.
clearhistory¶
/clearhistory ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Remove all records from the history list.
daq¶
/daq/fft/absolute ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Set to 1 to shift the frequencies in the FFT result so that the center frequency becomes the demodulation frequency rather than 0 Hz (when disabled).
/daq/fft/powercompensation ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Apply power correction to the spectrum to compensate for the shift that the window function causes.
/daq/fft/window ¶
| Properties: | Read, Write |
| Type: | Integer (enumerated) |
| Unit: | None |
The FFT window function to use (default 1 = Hann). Depending on the application, it makes a huge difference which of the provided window functions is used. Please check the literature to find out the best trade off for your needs.
| Value | Description |
|---|---|
| 0 | "rectangular": Rectangular |
| 1 | "hann": Hann |
| 2 | "hamming": Hamming |
| 3 | "blackman_harris": Blackman Harris 4 term |
| 16 | "exponential": Exponential (ring-down) |
| 17 | "cos": Cosine (ring-down) |
| 18 | "cos_squared": Cosine squared (ring-down) |
device¶
/device ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
The device ID to run the timeline experiment on, e.g., dev1000 (compulsory parameter).
historylength¶
/historylength ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Maximum number of entries stored in the measurement history.
mode¶
/mode ¶
| Properties: | Read, Write |
| Type: | Integer (enumerated) |
| Unit: | None |
The operating mode of the timeline module.
| Value | Description |
|---|---|
| 0 | "normal": Normal: the module controls and runs sequences on the device. |
| 1 | "listener": Listener: the module only receives data from the device without controlling it. |
save¶
/save/csvlocale ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
The locale to use for the decimal point character and digit grouping character for numerical values in CSV files: "C": Dot for the decimal point and no digit grouping (default); "" (empty string): Use the symbols set in the language and region settings of the computer.
/save/csvseparator ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
The character to use as CSV separator when saving files in this format.
/save/directory ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
The base directory where files are saved.
/save/fileformat ¶
| Properties: | Read, Write |
| Type: | Integer (enumerated) |
| Unit: | None |
The format of the file for saving data.
| Value | Description |
|---|---|
| 0 | "mat": MATLAB |
| 1 | "csv": CSV |
| 3 | "sxm": SXM (Image format) |
| 4 | "hdf5": HDF5 |
/save/filename ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
Defines the sub-directory where files are saved. The actual sub-directory has this name with a sequence count (per save) appended, e.g. timeline_000.
/save/save ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Initiate the saving of data to file. The saving is done in the background. When the save has finished, the module resets this parameter to 0.
/save/saveonread ¶
| Properties: | Read, Write |
| Type: | Integer (64 bit) |
| Unit: | None |
Automatically save the data to file immediately before reading out the data from the module using the read() command. Set this parameter to 1 if you want to save data to file when running the module continuously and performing intermediate reads.
sequence¶
/sequence/sourcestring ¶
| Properties: | Read, Write |
| Type: | String |
| Unit: | None |
The sequence program source code to compile and run on the device.
sigouts¶
/sigouts/n/modulation/type ¶
| Properties: | Read, Write |
| Type: | Integer (enumerated) |
| Unit: | None |
Digital modulation of the AWG output. Optionally mixes the waveform with an internal oscillator for frequency conversion. This feature is only available for instruments with the AWG option.
| Value | Description |
|---|---|
| 0 | "none": No modulation |
| 2 | "complex": Complex I/Q modulation of the AWG output. Mixes the waveform with the in-phase and quadrature components of an internal oscillator. |
/sigouts/1/modulation/type ¶
| Properties: | Read, Write |
| Type: | Integer (enumerated) |
| Unit: | None |
Digital modulation of the AWG output. Optionally mixes the waveform with an internal oscillator for frequency conversion. This feature is only available for instruments with the AWG option.
| Value | Description |
|---|---|
| 0 | "none": No modulation |
| 2 | "complex": Complex I/Q modulation of the AWG output. Mixes the waveform with the in-phase and quadrature components of an internal oscillator. |