API Reference Guide

Warning

This is the documentation for the old Vivace API. For the newer API compatible with both the Vivace and the Presto microwave platforms, see here.

This documentation is intended as a refence to the user who wants to program the Vivace 4 GHz platform by Intermodulation Products using the public application programming interface (API).

There are two main modes of operation:

  • In continuous-wave mode (vivace.lockin), the Vivace platform operates as a multifrequency lock-in amplifier. 32 frequencies can be synthesized and output with independent amplitudes and phases on 8 physical ports. The amplitude and phases of incoming signals on 8 physical ports are measured simultaneously at the same 32 frequencies.

  • In pulsed mode (vivace.pulsed), the user defines set of basic pulses (templates) and combines them in the time domain to design a complex experiment, much like a composer places a few basic notes in a musical score to design a symphony. 16 templates are available for each otuput port. The templates can be output directly, or used as envelopes for a digital sine-wave generator with programmable amplitude, frequency and phase. The templates can be triggered unconditionally, or conditioned on the result of a template-matching procedure on the input data. And much more…

Detailed information is provided in the documentation for each module.

lockin

Continuous-wave generation and measurement.

pulsed

Pulse-based experiment design and measurement.

utils

Collection of functions that might be useful, or might not.

version

Version information.


lockin module

Continuous-wave generation and measurement.

Detailed information is provided in the documentation for each class.

DirectLockin

Use the hardware in direct, continuous-wave mode.

MixLockin

Use the hardware in mixed, continuous-wave mode.


DirectLockin class

class vivace.lockin.DirectLockin(ext_ref_clk=False, force_reload=False, dry_run=False, address=None, port=None)

Use the hardware in direct, continuous-wave mode.

Direct mode means the generated signals are outputted directly, as opposed to being upconverted with the internal numerically-controlled oscillators. Same applies to the input signals, which are directly sampled rather than being downconverted with the internal NCOs.

Warning

Create only one instance at a time. This class is designed to be instantiated with Python’s with statement, see Examples section.

Parameters
  • ext_ref_clk (bool, optional) – if True configure the clock circuit to use an external reference

  • force_reload (bool, optional) – if True configure clock and load firmware even if there’s no change

  • dry_run (bool, optional) – if False don’t connect to hardware, for testing only

  • address (str, optional) – IP address or hostname of Vivace. If None, use factory default “192.168.42.50”.

  • port (int, optional) – port number of the server running on Vivace. If None, use factory default 3490.

Notes

In all the Examples, it is assumed that the imports import numpy as np and from vivace import lockin have been performed, and that this class has been instantiated in the form lck = lockin.DirectLockin(), or, much much better, using the with lockin.DirectLockin() as lck construct as below.

Examples

Output a continuous signal at 100 MHz with amplitude half of full scale from output port 1. Acquire 100 lock-in packets with 1 kHz bandwidth from all the input ports.

>>> from vivace import lockin
>>> with lockin.DirectLockin() as lck:
>>>     f, df = lck.tune(100e+6, 1e+3)
>>>     lck.set_df(df)
>>>     lck.set_frequencies(f)
>>>     lck.set_amplitudes(0.5, port=1)
>>>     lck.apply_settings()
>>>     lck.start_lockin()
>>>     data = lck.get_pixels(100)
>>>     lck.stop_lockin()
>>> data.shape
connecting to 192.168.42.50 port 3490
(100, 8, 32)

See also

MixLockin

apply_settings()

Apply the settings to the hardware.

Notes

Prior to a call to this function, any change of settings has no effect on the hardware.

Examples

>>> f, df = lck.tune(100e6, 1e3)
>>> lck.set_df(df)
>>> lck.set_frequencies(f)
>>> lck.set_amplitudes(0.5)
>>> lck.apply_settings()
blank_output(blank, port=None)

Disable the output port(s). Has no effect on the DC bias.

The new setting is applied immediately.

Parameters
  • blank (bool) – When True, disable the RF output.

  • port (int or array_like, optional) – Output port, if None set blank for all ports. Valid ports are in the interval [1, 8].

Raises

ValueError – If port is outside valid range.

close()

Gracely disconnect from the hardware.

Call this method if the class was instantiated without a with statement. This method is called automatically when exiting a with block and before the object is destructed.

get_Tm()

Get measurement time.

The inverse of the measurement bandwidth.

Returns

Tm – Measurement time in seconds.

Return type

float

See also

get_df

get_amplitudes(port=None)

Get the lock-in output amplitudes.

Parameters

port (int or array_like, optional) – Output port(s), if None return amplitudes for all ports. Valid ports are in the interval [1, 8].

Returns

amps – Output amplitudes for each frequency with +/- 1.0 being full scale. If port is int, a 1d array with shape (nr_frequencies,). If port is list or None, a 2d array with shape (nr_ports, nr_freqs). dtype is float.

Return type

numpy.ndarray

get_df()

Get measurement bandwidth.

Returns

df – Measurement bandwith in Hz.

Return type

float

See also

get_Tm

get_dt(which='adc')

Get sample spacing.

The inverse of the sampling frequency.

Returns

  • dt (float) – Sample spacing in seconds.

  • which ({“adc”, “dac”}, optional) – analog-to-digital (input) or digital-to-analog (output) converter

See also

get_fs

get_frequencies(which='adc')

Get the lock-in frequencies.

Parameters

which ({"adc", "dac"}, optional) – analog-to-digital (input) or digital-to-analog (output) converter

Returns

freqs – Lock-in frequencies in Hz. dtype is float

Return type

numpy.ndarray

get_fs(which='adc')

Get sampling frequency.

Returns

  • fs (float) – Sampling rate in Hz.

  • which ({“adc”, “dac”}, optional) – analog-to-digital (input) or digital-to-analog (output) converter

See also

get_dt

get_ns(which='adc')

Get number of samples per lock-in window.

The sampling rate divided by the measurement bandwidth.

Parameters

which ({"adc", "dac"}, optional) – analog-to-digital (input) or digital-to-analog (output) converter

Returns

ns

Return type

int

get_phases(port=None, deg=False)

Get the lock-in output phases.

Parameters
  • port (int or array_like, optional) – Output port(s), if None return phases for all ports. Valid ports are in the interval [1, 8].

  • deg (bool, optional) – Set the phases in degrees in [-180.0, +180.0]. Default is radians in [-np.pi, +np.pi].

Returns

phases – Output phases in rad/deg for each frequency. If port is int, a 1d array with shape (nr_frequencies,). If port is list or None, a 2d array with shape (nr_ports, nr_freqs). dtype is float.

Return type

numpy.ndarray

get_pixels(n)

Get lock-in packets (pixels) from the local buffer.

Parameters

n (int) – The number of lock-in packets to extract from the local buffer.

Returns

pixels – Measured lock-in data in ratio of full-scale input. shape is (n, nr_ports, nr_frequencies). dtype is complex.

Return type

numpy.ndarray

Notes

This method locks until at least n measured packets are available in the local buffer. Remember to start/stop the lock-in measurement before/after calling this method.

Examples

>>> lck.start_lockin()
>>> pixels = lck.get_pixels(1000)
>>> lck.stop_lockin()
>>> pixels.shape
(1000, 8, 32)
get_time_data(port, ns=None)

Get input data in the time domain.

Parameters
  • port (int) – Input port in interval [1, 8].

  • ns (int) – Number of samples to acquire. If None, use get_ns() to match a lock-in window.

Returns

data – Measured input data with +/- 1.0 being full scale. dtype is float.

Return type

numpy.ndarray

set_Tm(Tm)

Set measurement time.

The new setting is not applied until apply_settings() is called!

Parameters

Tm (float) – Measurement time in seconds.

Returns

Tm_set – The measurement time in seconds (that will be) set in the hardware.

Return type

float

set_amplitudes(amps, port=None)

Set the lock-in output amplitudes.

The new setting is not applied until apply_settings() is called!

Parameters
  • amps (float or array_like) – Output amplitudes with +/- 1.0 being full scale. If less than available number of frequencies, set the rest to zero.

  • port (int or array_like, optional) – Output port, if None set amplitudes for all ports. Valid ports are in the interval [1, 8].

Returns

amps_set – Output amplitudes (that will be) set in the hardware. If port is int, a 1d array with shape (nr_frequencies,). If port is list or None, a 2d array with shape (nr_ports, nr_freqs). dtype is float.

Return type

numpy.ndarray

set_df(df)

Set measurement bandwith.

The new setting is not applied until apply_settings() is called!

Parameters

df (float) – Measurement bandwith in Hz.

Returns

df_set – The measurement bandwith in Hz (that will be) set in the hardware.

Return type

float

Examples

>>> f, df = lck.tune([100e+6, 231e+6], 1e+3)
>>> lck.set_df(df)
>>> lck.set_frequencies(f)
>>> lck.apply_settings()
set_frequencies(freqs)

Set the lock-in frequencies.

The new setting is not applied until apply_settings() is called!

Parameters

freqs (float or array_like) – Lock-in frequency/ies in Hz. If less than available number of frequencies, the rest is set to zero.

Returns

freqs_set – The frequencies in Hz (that will be) set in the hardware. dtype is float.

Return type

numpy.ndarray

Notes

This function performs no tuning, make sure freqs are tuned to the user needs before calling this function.

Examples

>>> f, df = lck.tune([100e+6, 231e+6], 1e+3)
>>> lck.set_df(df)
>>> lck.set_frequencies(f)
>>> lck.apply_settings()
set_ns(ns, which='adc')

Set number of samples per lock-in window.

The sampling rate divided by the measurement bandwidth.

The new setting is not applied until apply_settings() is called!

Parameters
  • ns (int) –

  • which ({"adc", "dac"}, optional) – analog-to-digital (input) or digital-to-analog (output) converter

Returns

ns_set – The number of samples (that will be) set in the hardware.

Return type

int

set_output_bias(bias, port=None)

Set a DC bias on the output ports.

The new setting is applied immediately.

Parameters
  • bias (float) – DC bias with +/- 1.0 being full scale.

  • port (int or array_like, optional) – Output port, if None set DC bias for all ports. Valid ports are in the interval [1, 8].

Raises

ValueError – If bias or port are outside valid range.

set_phases(phases, port=None, deg=False)

Set the lock-in output phases.

The new setting is not applied until apply_settings() is called!

Parameters
  • phases (float or array_like) – Output phases in rad/deg. If less than available number of frequencies, set the rest to zero.

  • port (int or array_like, optional) – Output port, if None set phases for all ports. Valid ports are in the interval [1, 8].

  • deg (bool, optional) – Set the phases in degrees in [-180.0, +180.0]. Default is radians in [-np.pi, +np.pi].

Returns

phases_set – Output phases in rad/deg (that will be) set in the hardware. If port is int, a 1d array with shape (nr_frequencies,). If port is list or None, a 2d array with shape (nr_ports, nr_freqs). dtype is float.

Return type

numpy.ndarray

start_lockin()

Initiate the transfer of lock-in packets from the hardware.

See also

get_pixels

for example usuage.

stop_lockin(empty_buffer=True)

Stop the transfer of lock-in packets from the hardware.

Parameters

empty_buffer (bool, optional) – Empty local buffer of lock-in packets to avoid reading old data.

See also

get_pixels

for example usuage.

tune(f, df)

Perform perfect level of tuning.

This provides frequencies that might be further from the requested ones, but with zero Fourier leakage. See Notes.

Parameters
  • f (float or array_like) – Target frequency/ies in Hz

  • df (float) – Target measurement bandwidth in Hz

Returns

  • f_tuned (float or numpy.ndarray) – Tuned frequency/ies in Hz

  • df_tuned (float) – Tuned measurement bandwith in Hz

See also

tune_approx

approximate tuning

Notes

First, this level of tuning forces the measurement bandwith df to divide the sampling frequency fs by a power of 2, i.e. the number of samples in each lock-in measurement window is a power of 2: ns = fs/df_tuned = 2**m. Second, the tuning forces each frequency f to be integer multiple of the measurement bandwith df_tuned, i.e. there is an integer number n = f_tuned/df_tuned of oscillations within each measurement window.

This level of tuning always allows for measurement without Fourier leakage, or spectral leakage, and guarantees that f_tuned can be represented exactly in the hardware (see Examples).

Examples

>>> f, df = 100e+6, 1e+3
>>> f_tuned, df_tuned = lck.tune(f, df)
>>> df_set = lck.set_df(df_tuned)
>>> f_set = lck.set_frequencies(f_tuned)[0]
>>> df, df_tuned, df_set
(1000.0, 953.67431640625, 953.67431640625)
>>> f, f_tuned, f_set
(100000000.0, 100000381.46972656, 100000381.46972656)
>>> lck.get_fs() / df_set
1048576.0  # power of 2
>>> f_set / df_set
104858.0  # integer
tune_approx(f, df)

Perform approximate level of tuning.

This provides frequencies closer to the requested ones, with a level of Fourier leakage that is adequate to most experiments. See Notes.

Parameters
  • f (float or array_like) – Target frequency/ies in Hz

  • df (float) – Target measurement bandwidth in Hz

Returns

  • f_tuned (float or numpy.ndarray) – Tuned frequencies in Hz

  • df_tuned (float) – Tuned measurement bandwith in Hz

See also

tune

perfect tuning

Notes

First, this level of tuning forces the measurement bandwith df to be a divisor of the sampling frequency fs, i.e. there is an integer number of samples ns = fs/df_tuned in each lock-in measurement window. Second, the tuning forces each frequency f to be integer multiple of the measurement bandwith df_tuned, i.e. there is an integer number n = f_tuned/df_tuned of oscillations within each measurement window.

In theory, this level of tuning allows for measurement without Fourier leakage, or spectral leakage. In practice, however, not every value of f_tuned can be represented exactly in the hardware. With this level of tuning, the frequency that is actually set in hardware f_set is slightly different from the tuned frequency f_tuned. Therefore, the ratio f_set/df_tuned is not an integer, and some Fourier leakage occurs. To avoid long-term phase drift, the phase of the oscillation at frequency f_set is reset at the end of each lock-in window (every 1/df_tuned).

In most applications, however, the difference between f_set and f_tuned is really small (see Examples) so that the resulting Fourier leakage and the phase-reset glitches are well below the noise level.

Examples

>>> f, df = 100e+6, 1e+3
>>> f_tuned, df_tuned = lck.tune_approx(f, df)
>>> df_set = lck.set_df(df_tuned)
>>> f_set = lck.set_frequencies(f_tuned)[0]
>>> df, df_tuned, df_set
(1000.0, 1000.0, 1000.0)
>>> f, f_tuned, f_set
(100000000.0, 100000000.0, 100000000.0003638)
>>> lck.get_fs() / df_set
1000000.0  # integer
>>> f_set / df_set
100000.0000003638  # not exact integer

MixLockin class

class vivace.lockin.MixLockin(ext_ref_clk=False, force_reload=False, dry_run=False, dac_freq=5.0, address=None, port=None)

Bases: vivace.lockin.DirectLockin

Use the hardware in mixed, continuous-wave mode.

Mixed mode means the generated signals are upconverted using the internal numerically controlled oscillators (NCO). Each pair of output ports in the API is connected to the I and Q ports of a digital IQ mixer, and therefore mapped onto a single physical output port. The same applies to the input signals, which are downconverted using the internal NCOs and each physical input port is mapped onto a pair of input ports in the API representing the I and Q demodulated signals from the digital IQ mixers.

Warning

Create only one instance at a time. This class is designed to be instantiated with Python’s with statement, see Examples section.

Parameters
  • ext_ref_clk (bool, optional) – if True configure the clock circuit to use an external reference

  • force_reload (bool, optional) – if True configure clock and load firmware even if there’s no change

  • dry_run (bool, optional) – if False don’t connect to hardware, for testing only

  • dac_freq (float, optional) – the frequency of the digital-to-analog converters in GS/s. Only 4.0, 5.0 (default) and 6.0 are supported at the moment.

  • address (str, optional) – IP address or hostname of Vivace. If None, use factory default “192.168.42.50”.

  • port (int, optional) – port number of the server running on Vivace. If None, use factory default 3490.

Notes

To use single-sideband modulation, set the same amplitude for the I and Q ports: \(A_\mathrm{I}=A_\mathrm{Q}\). To upconvert to the higher sideband, set the phases as \(\phi_\mathrm{Q}=\phi_\mathrm{I} - \frac{\pi}{2}\); for the lower sideband set \(\phi_\mathrm{Q}=\phi_\mathrm{I} + \frac{\pi}{2}\). Following the same convention, you can use untwist_downconversion to obtain the lower and higher side bands from measured I and Q data. When using external mixers, a different convention might be used: check with the mixer vendor, or test.

In all the Examples, it is assumed that the imports import numpy as np and from vivace import lockin have been performed, and that this class has been instantiated in the form lck = lockin.MixLockin(), or, much much better, using the with lockin.MixLockin() as lck construct as below.

Examples

Output a continuous signal at 3.9 GHz with amplitude half of full scale from output port 1. Use a 3.8 GHz carrier and a 100 MHz signal with upper-sideband (HSB) modulation. Acquire 100 lock-in packets with 1 kHz bandwidth from all the input ports.

>>> from vivace import lockin
>>> with lockin.MixLockin() as lck:
>>>     lck.configure_mixer(
>>>         freq=3.8e+9,  # set NCO to 3.8 GHz
>>>         in_ports=[1, 2, 3, 4],
>>>         out_ports=1,
>>>     )
>>>     f, df = lck.tune(100e+6, 1e+3)
>>>     lck.set_df(df)
>>>     lck.set_frequencies(f)  # set intermediate frequency to 100 MHz
>>>     lck.set_amplitudes(0.5, port=[1, 2])
>>>     lck.set_phases(0.0, port=1)  # I port for output 1
>>>     lck.set_phases(-np.pi / 2, port=2)  # Q port for output 1, upconvert to HSB
>>>     lck.apply_settings()
>>>     lck.start_lockin()
>>>     data = lck.get_pixels(100)
>>>     lck.stop_lockin()
>>> data.shape
connecting to 192.168.42.50 port 3490
(100, 8, 32)

See also

DirectLockin

configure_mixer(freq, *, in_ports=None, out_ports=None, in_zone=None, out_zone=None)

Configure the built-in digital mixers for up and down conversion.

The new settings are applied immediately.

Parameters
  • freq (float) – Frequency in Hz for the numerically-controlled oscillator (NCO).

  • in_ports (int or array_like, optional) – Input port(s). Valid ports are in the interval [1, 8].

  • out_ports (int or array_like, optional) – Output port(s). Valid ports are in the interval [1, 8].

  • in_zone (int, optional) – Nyquist zone for input_ports. If None (default), set based on in_freq and ADC sample rate.

  • out_zone (int, optional) – Nyquist zone for output_ports. If None (default), set based on out_freq and DAC sample rate.

Raises

ValueError – If freq is above 10 GHz; if neither in_ports nor out_ports are given.

get_time_data(port, ns=None)

Get IQ input data in the time domain.

Parameters
  • port (int) – Input port in interval [1, 8].

  • ns (int) – Number of samples to acquire. If None, use get_ns() to match a lock-in window.

Returns

data – Measured IQ input data with +/- 1.0 being full scale. The shape is (2, ns), with data[0, :] the I quadrature and data[1, :] the Q quadrature. dtype is float.

Return type

numpy.ndarray

set_mixer_frequency(freq, in_port=None, out_port=None)

Set the frequency of the internal NCOs for up/downconversion.

Deprecated since version 1.4.0: Use configure_mixer() instead.

The new setting is applied immediately.

Parameters
  • freq (float) – Carrier frequency in Hz.

  • in_port (int or array_like, optional) – Input port. Valid ports are in the interval [1, 8].

  • out_port (int or array_like, optional) – Output port. Valid ports are in the interval [1, 8].

Notes

If neither in_port nor out_port are supplied, set for all input and output ports.

set_nyquist_zone(zone, in_port=None, out_port=None)

Set the Nyquist zone for the data converters.

Deprecated since version 1.4.0: Use configure_mixer() instead.

The new setting is applied immediately.

Parameters
  • zone (int) – 1 is for DC to fs/2, 2 is for fs/2 to fs, and so on.

  • in_port (int or array_like) – Input port. Valid ports are in the interval [1, 8].

  • out_port (int or array_like, optional) – Output port. Valid ports are in the interval [1, 8].

Notes

If neither in_port nor out_port are supplied, set for all input and output ports.


pulsed module

Pulse-based experiment design and measurement.

Detailed information is provided in the documentation for each class.

Pulsed

Use the hardware in pulsed mode.

TrigEvent

Container for trigger events.

LongDrive

Container for a long pulse.

Module constants:

vivace.pulsed.MAX_LUT_ENTRIES = 512

maximum length of frequency/phase and scale look-up tables

Type

int

vivace.pulsed.MAX_TRIGGERS = 32768

maximum number of trigger events in an experiment sequence

Type

int

vivace.pulsed.MAX_PERIOD = 8.5

maximum duration in seconds of a single experiment repetition

Type

float

vivace.pulsed.MAX_STORE_DURATION = 4.096e-06

maximum duration in seconds of a contiguous acquisition window

Type

float

vivace.pulsed.MAX_TEMPLATE_LEN = 4088

maximum number of data points in a single template slot

Type

int

vivace.pulsed.MAX_THRESHOLD = 8590458904.000975

maximum threshold/result value for a template match

Type

float


Pulsed class

class vivace.pulsed.Pulsed(ext_ref_clk=False, force_reload=False, dry_run=False, address=None, port=None)

Use the hardware in pulsed mode.

Warning

Create only one instance at a time. Use each instance for only one measurement. This class is designed to be instantiated with Python’s with statement, see Examples section.

Parameters
  • ext_ref_clk (bool, optional) – if True configure the clock circuit to use an external reference.

  • force_reload (bool, optional) – if True configure clock and load firmware even if there’s no change from the previous settings.

  • dry_run (bool, optional) – if False don’t connect to hardware, for testing only.

  • address (str, optional) – IP address or hostname of Vivace. If None, use factory default “192.168.42.50”.

  • port (int, optional) – port number of the server running on Vivace. If None, use factory default 3490.

Notes

In all the Examples, it is assumed that the imports import numpy as np and from vivace import pulsed have been performed, and that this class has been instantiated in the form pls = pulsed.Pulsed(), or, much much better, using the with pulsed.Pulsed() as pls construct as below.

Examples

Output a 2 ns pulse on output port 1 every 100 \(\mu\)s, and sample 1 \(\mu\)s of data from input port 1. Repeat 10 times, average 10_000 times.

>>> from vivace import pulsed
>>> with pulsed.Pulsed() as pls:
>>>     pls.set_store_ports(1)
>>>     pls.set_store_duration(1e-6)
>>>     pulse = pls.setup_template(1, np.ones(8))
>>>     pls.output_pulse(0.0, pulse)
>>>     pls.store(0.0)
>>>     t_arr, data = pls.perform_measurement(100e-6, 10, 10_000, print_time=True)
connecting to 192.168.42.50 port 3490
Expected runtime: 10.0s
Total time: 10.2s
Transfering data: 3.0ms
blank_output(blank, port=None)

Disable the output port(s). Has no effect on the DC bias.

The new setting is applied immediately.

Parameters
  • blank (bool) – When True, disable the RF output.

  • port (int or array_like, optional) – Output port, if None set blank for all ports. Valid ports are in the interval [1, 8].

Raises

ValueError – If port is outside valid range.

close()

Gracely disconnect from the hardware.

Call this method if the class was instantiated without a with statement. This method is called automatically when exiting a with block and before the object is destructed.

get_template_matching_data(input_pairs)

Obtain from hardware the result of the template matching.

Only valid after the measurment is performed.

Parameters

input_pairs (TrigEvent or list of TrigEvent) – One or more template-matching pairs as defined by setup_template_matching_pair().

Returns

ret – For each element (input template) of input_pairs, ret contains a numpy.ndarray with the template-matching results for that template. Therefore, len(input_pairs) == len(ret). dtype is float. The data is scaled such that a perfect match of a full-scale cosine over a time T is 0.5 * T.

Return type

list

Raises
  • RuntimeError – If no template-matching data is available.

  • TypeError – If input_pairs contains unrecognized objects.

match(at_time, template_info)

Program hardware to perform template matching at given time.

Parameters
  • at_time (float) – At what time in seconds the template(s) should be matched.

  • template_info (TrigEvent or list of TrigEvent) – The information about one or more template-matching pairs as obtained from setup_template_matching_pair().

Raises

TypeError – If template_info contains unrecognized objects.

next_frequency(at_time, output_ports)

Program the hardware to move to the next frequency/phase at given time.

Parameters
  • at_time (float) – At what time in seconds the change should happen. Will be rounded to a multiple of 2 ns.

  • output_ports (int or list of int) – What output ports should be affected by the change. Valid ports are in the interval [1, 8].

Raises

ValueError – If any of output_ports is out of [1, 8].

See also

setup_freq_lut

next_scale(at_time, output_ports)

Program the hardware to move to the next output scale at given time.

Parameters
  • at_time (float) – At what time in seconds the change should happen. Will be rounded to a multiple of 2 ns.

  • output_ports (int or list of int) – What output ports should be affected by the change. Valid ports are in the interval [1, 8].

Raises

ValueError – If any of output_ports is out of [1, 8].

See also

setup_scale_lut

output_digital_marker(at_time, duration, ports)

Program hardware to output a digital marker at given time.

Parameters
  • at_time (float) – At what time in seconds the marker should be output.

  • duration (float) – For how long in seconds the marker should be output.

  • port (int or list of int) – The digital output port(s) the marker should be output from. Valid values are in [1, 4].

Raises

ValueError – If ports is out of range.

output_pulse(at_time, pulse_info)

Program hardware to output pulse(s) at given time.

Parameters
Raises

TypeError – If pulse_info contains unrecognized objects.

perform_measurement(period, repeat_count, num_averages, print_time=False, verbose=False, sleep_func=None)

Execute the experiment planned so far. Can be time consuming!

The method will lock until the measurement and the data transfer are completed.

Parameters
  • period (float) – Measurement time in seconds for one repetition. Should be long enough to include the last event programmed. If it is longer, there will be some waiting time between repetitions.

  • repeat_count (int) – Number of times to repeat the experiment and stack the acquired data (no averaging).

  • num_averages (int) – Number of times to repeat the whole sequence (including the repetitions due to repeat_count) and average the acquired data.

  • print_time (bool, optional) – If True, print to standard output the expected runtime before the experiment, the total runtime after the experiment, and print during the experiment the estimated time left at regular intervals.

  • verbose (bool, optional) – If True, print debugging information.

  • sleep_func (callable, optional) – A function to be called periodically while waiting for the experiment to be done. sleep_func should accept one float as argument representing the sleep time in seconds. If not supplied, use time.sleep().

Returns

  • t_arr (numpy.ndarray) – The time axis in seconds during one acquisition. dtype is float.

  • data (numpy.ndarray) – The acquired data with 4 GS/s sample rate and scaled to +/-1.0 being full-scale input. The shape of the array is (num_stores * repeat_count, num_ports, smpls_per_store), where num_stores is number of store events programmed in a sequence with the store() method, num_ports is the number of inputs ports set with set_store_ports(), and smpls_per_store is the number of samples in one acquisition set by set_store_duration(). dtype is float.

Raises
  • ValueError – If period is negative or greater than MAX_PERIOD; if period is too small to fit the last event; if repeat_count is not positive; if num_averages is not positive.

  • RuntimeError – If the sequence requires more triggers than MAX_TRIGGERS; if more than 8 envelopes are used for the same carrier; if too much average data or template-matching data is requested.

Notes

A running measurement can be aborted by hitting Ctrl+C once in the Python interpreter. The measurement will be stopped, the outputs blanked, and the data collected so far downloaded. Pressing Ctrl+C again will raise a KeyboardInterrupt exception.

select_frequency(at_time, index, output_ports)

Program the hardware to select a frequency/phase at given time.

Parameters
  • at_time (float) – At what time in seconds the change should happen. Will be rounded to a multiple of 2 ns.

  • index (int) – Zero-based index in look-up table to select. Valid indexes are in the interval [0, 511].

  • output_ports (int or list of int) – What output ports should be affected by the change. Valid ports are in the interval [1, 8].

Raises

ValueError – If any of output_ports is out of [1, 8]; if index is out of [0, 511].

See also

setup_freq_lut

select_scale(at_time, index, output_ports)

Program the hardware to select an output scale at given time.

Parameters
  • at_time (float) – At what time in seconds the change should happen. Will be rounded to a multiple of 2 ns.

  • index (int) – Zero-based index in look-up table to select. Valid indexes are in the interval [0, 511].

  • output_ports (int or list of int) – What output ports should be affected by the change. Valid ports are in the interval [1, 8].

Raises

ValueError – If any of output_ports is out of [1, 8]; if index is out of [0, 511].

See also

setup_scale_lut

set_output_bias(bias, port=None)

Set a DC bias on the output ports.

The new setting is applied immediately.

Parameters
  • bias (float) – DC bias with +/- 1.0 being full scale.

  • port (int or array_like, optional) – Output port, if None set DC bias for all ports. Valid ports are in the interval [1, 8].

Raises

ValueError – If bias or port are outside valid range.

set_store_duration(T)

Set the duration of all data acquisition events.

Parameters

T (float) – Duration in seconds.

Raises

ValueError – If duration is negative or greater than MAX_STORE_DURATION.

set_store_ports(input_ports)

Set input port(s) for all data acquisition events.

Parameters

input_ports (int or list of int) – Valid ports are in the interval [1, 8].

Raises

ValueError – If any of input_ports is out of [1, 8].

setup_HL_readout(input_port, frequency, duration, threshold=0.0)

Create input templates for high/low sideband demodulation from an external IQ mixer.

Parameters
  • input_port (int) – Valid ports are in [1, 3, 5, 7]. input_port is considered as the I port of the mixer, and input_port + 1 as the Q port.

  • frequency (float) – Demodulation frequency in Hz. Valid range is [0.0, fsample/2).

  • duration (float) – Demodulation window in seconds. Will be rounded to multiples of 250 ps.

  • threshold (float, optional) – Level for discrimination between a successfull and failed comparison. The scale is such that a perfect match of a full-scale cosine over a time T is 0.5 * T.

Returns

triginfo

Return type

list of TrigEvent

setup_condition(input_pairs, output_templates_true, output_templates_false=None)

Setup a template-matching condition for one or more output pulses.

The pulses in output_templates_true (output_templates_false) will be marked as conditional, and will be output if and only if all the template-matching conditions defined in input_pairs are (not) satisfied.

Parameters
setup_freq_lut(output_ports, carrier, frequencies, phases, repeat_count=1)

Setup look-up table for frequency generator.

Parameters
  • output_ports (int or array_like) – Valid ports are in the interval [1, 8].

  • carrier (int) – Valid carriers are in the interval [1, 2].

  • frequencies (float or array_like) – Frequency/ies in Hz for the generator.

  • phases (float or array_like) – Phase(s) in rad for the generator. Must be same length as frequencies.

  • repeat_count (int, optional) – The frequency/phase will be updated every repeat_count calls to next_frequency(). Must be a power of 2 between 1 and 512. Useful for bidimensional sweeps.

Raises

ValueError – If any of output_ports is out of [1, 8]; if any of frequencies is out of [0.0, 2e+9); if carrier is out of [1, 2]; if phases doesn’t have the same shape as frequencies; if the LUTs are longer than MAX_LUT_ENTRIES; if repeat_count is not a power of 2 smaller than 512.

See also

next_frequency

setup_long_drive(output_port, carrier, duration, amplitude=1.0, rise_time=0.0, fall_time=0.0, use_scale=False, output_marker=None)

Create a long output pulse with constant amplitude.

Useful for using fewer templates.

Parameters
  • output_port (int) – Valid ports are in the interval [1, 8].

  • carrier (int) – The carrier to use for this pulse, valid carriers are in the interval [1, 2].

  • duration (float) – Total length of the pulse in seconds. Will be rounded to a multiple of 2 ns.

  • amplitude (float, optional) – Amplitude of the flat part of the pulse.

  • rise_time (float, optional) – Smoothen the initial rise_time seconds of the pulse. Will be rounded to a multiple of 2 ns. See Notes.

  • fall_time (float, optional) – Smoothen the final fall_time seconds of the pulse. Will be rounded to a multiple of 2 ns. See Notes.

  • use_scale (bool, optional) – If True, scale the amplitude with the global output scaler.

  • output_marker (int, optional) – Output a high value from digital output number output_marker for the duration of the pulse. If None (default), no marker is output. Valid ports are in [1, 4].

Returns

long_drive

Return type

LongDrive

Raises
  • RuntimeError – If there are not enough templates available for output_port.

  • ValueError – If output_port is out of [1, 8]; if carrier is out of [1, 2]; if amplitude is out of [-1.0, +1.0]; if output_marker is out of range, if rise_time or fall_time are invalid.

Notes

A long drive is always used as an envelope. Regardless of duration, only one template is consumed for a flat long drive. When rise_time and/or fall_time are nonzero, one additional template is used for each rise and fall segments. The rise and fall times are subtracted from the flat time, so that the total duration of the pulse including transients is duration. The rise and fall shapes are \(\sin(\frac{\pi}{2}x)^2\) and \(\cos(\frac{\pi}{2}x)^2\), respectively, with \(x \in [0, 1)\).

For implementation details, rise_time and fall_time are limited to 1022 ns.

See also

setup_template

create a custom template/envelope.

output_pulse

program hardware to output the generated pulse.

setup_scale_lut(output_ports, scales, repeat_count=1)

Setup look-up table for global output scale.

Parameters
  • output_ports (int or array_like) – Valid ports are in the interval [1, 8].

  • scales (float or array_like) – Output scale in ratio of full scale.

  • repeat_count (int) – The scale will be updated every repeat_count calls to next_scale(). Must be a power of 2 between 1 and 512. Useful for bidimensional sweeps.

Raises

ValueError – If any of output_ports is out of [1, 8]; if any of scales is out of [-1.0, +1.0]; if the LUT is longer than MAX_LUT_ENTRIES, if repeat_count is not a power of 2 smaller than 512.

See also

next_scale

setup_template(output_port, template, envelope=0, use_scale=False, output_marker=None)

Create an output template or envelope.

Parameters
  • output_port (int) – Valid ports are in the interval [1, 8].

  • template (np.ndarray of np.float64) – Data points for the template/envelope with 4 GS/s sampling rate, i.e. 250 ps spacing. Valid range is [-1.0, +1.0].

  • envelope (int, optional) – If > 0 set up an envelope instead of a template using carrier number envelope; if 0 set up a template.

  • use_scale (bool, optional) – If True, scale the amplitude with the global output scaler.

  • output_marker (int, optional) – Output a high value from digital output number output_marker for the duration of the pulse. If None (default), no marker is output. Valid ports are in [1, 4].

Returns

triginfo

Return type

list of TrigEvent

Raises
  • RuntimeError – If there are not enough templates available for output_port.

  • ValueError – If output_port is out of [1, 8]; if any sample in template is out of [-1.0, +1.0]; if envelope ` is out of `[0, 2].

Notes

If the length of the pulse is longer than a single template slot, the pulse is automatically split into multiple segments of appropriate length. Therefore, the pulse migth use more than one template slot.

See also

setup_long_drive

create a long flat pulse using fewer templates.

output_pulse

program hardware to output the generated template.

setup_template_matching_pair(input_port, template1, template2=None, threshold=0.0, compare_next_port=False)

Create a pair of input templates for template matching.

The result of template matching can be obtained after the measurement with get_template_matching_data(). The matching also defines a condition that can be used to mask one or more output templates during the measurement with setup_condition(). The template-matching condition is True if the match with template1 plus the match with template2 is greater or equal than threshold, False otherwise.

Parameters
  • input_port (int) – Valid ports are in the interval [1, 8]. If compare_next_port=True, it must be odd.

  • template1 (numpy.ndarray) –

  • template2 (numpy.ndarray, optional) – Data points for the templates with 4 GS/s sampling rate, i.e. 250 ps spacing. Valid range is [-1.0, +1.0]. If template2 is not provided, it will be set to all zeros. dtype is float

  • threshold (float, optional) – Level for discrimination between a successfull and failed comparison. The scale is such that a perfect match of a full-scale cosine over a time T is 0.5 * T.

  • compare_next_port (bool, optional) – If True, match template1 from input_port and template2 from input_port+1. If False, match both from input_port.

Returns

triginfo

Return type

list of TrigEvent

Raises

Notes

To evaluate a match, the input data acquired from port input_port is first multiplied with each template element-wise, and then summed. If the match using template1 is larger or equal than the match using template2, the match is considered successful.

store(at_time)

Program hardware to acquire data from the input ports at given time.

Parameters

at_time (float) – At what time in seconds the acquisition should start. Will be rounded to a multiple of 2 ns.

Raises

RuntimeError – If the store duration and the input ports have not been set up.

Notes

The input ports and the duration of the acquisition are set up separately, see See also section below.


TrigEvent class

class vivace.pulsed.TrigEvent(action, **kwargs)

Bases: object

Container for trigger events.

Used as return type by many methods of Pulsed. The user doesn’t need to instantiate this class in any common situation.

Depending on the type of event, some of the following attributes may be defined:

action

Type of event, always defined.

Type

str

duration

Length of the event in clock cycles.

Type

int

duration_s

Length of the event in seconds.

Type

float

envelope

If True, the template is used as an envelope.

Type

bool

offset

Shift event in time by offset clock cycles.

Type

int

offset_s

Shift event in time by offset_s seconds.

Type

float

port

Input/output port [0, 7] associated with the event. Note the zero-based indexing.

Type

int

template

Template index [0, 15] associated with the event. Note the zero-based indexing.

Type

int

index

Index of look-up table to select

Type

int

Parameters
  • action (str) – Type of trigger event. E.g. ‘store’, ‘readout’, ‘carrier’, …

  • **kwargs – Any additional keyword argument is set as a public attribute.

copy()

Return a shallow copy of this object.

Returns

Return type

TrigEvent

get_cmp_key()

Return a comparison key for sorted().

Returns

Return type

list


LongDrive class

class vivace.pulsed.LongDrive(triginfo, total_duration, rise_time, fall_time, use_scale, dig_out)

Bases: object

Container for a long pulse.

Used as return type by Pulsed.setup_long_drive(). The user doesn’t need to instantiate this class in any common situation. However, it can be useful to use the methods defined by this class to update the duration of a previously defined long pulse.

Parameters
  • triginfo (list of TrigEvent) – Information about one long pulse as obtained by Pulsed.setup_long_drive()

  • total_duration (float) – Total length of the pulse in seconds.

  • rise_time (float) – Rise time in seconds.

  • fall_time (float) – Fall time in seconds.

  • use_scale (bool) – If True, scale the amplitude with the global output scaler.

  • dig_out (int) – If not None, output a marker on digital out dig_out during the duration of the pulse.

Raises

AssertionError – if the provided parameters are not consisten with triginfo

update_flat_duration(new_duration)

Update the pulse by changing the duration of the flat part.

Rise and fall times are not affected. The new total duration will be new_duration + rise_time + fall_time.

Parameters

new_duration (float) – New duration in seconds for the flat part of the long pulse. Will be rounded to a multiple of 2 ns.

Raises

ValueError – if new_duration is not valid.

update_total_duration(new_duration)

Update the pulse by changing the total duration of the pulse.

Rise and fall times are not affected. The new duration of the flat part will be new_duration - rise_time - fall_time.

Parameters

new_duration (float) – New total duration in seconds of the long pulse. Will be rounded to a multiple of 2 ns.

Raises

ValueError – if new_duration is not valid.


utils module

Collection of functions that might be useful, or might not.

vivace.utils.as_flat_list(x)

Return x as a flat unidimensional list.

Parameters

x (object) – An arbitrarily nested list, tuple, np.ndarray, or a mixture thereof.

Returns

A flat, unidimensional list with all the objects of x.

Return type

list

vivace.utils.format_sec(s)

Format a time interval in seconds into a more human-readable string.

Parameters

s (float) – time interval in seconds

Returns

time interval in the form “Xh Ym Z.zs”

Return type

str

Examples

>>> format_sec(np.pi * 1e+8)
'9y 348d 20h 27m 45.4s'
>>> format_sec(np.exp(-10))
'45.4us'
vivace.utils.get_sourcecode(script_filename)

Open a file and return its content.

Parameters

script_filename (str) – Path to the file.

Returns

a list whose elements are the lines of the file at script_filename

Return type

list of str

vivace.utils.sin2(nr_samples)

Create a \(\sin^2\) envelope/template.

Parameters

nr_samples (int) –

Returns

Return type

np.ndarray of np.float64

vivace.utils.sinP(P, nr_samples)

Create a \(\sin^P\) envelope/template.

Parameters
  • P (int) –

  • nr_samples (int) –

Returns

Return type

np.ndarray of np.float64

vivace.utils.ssh_connect(address='192.168.42.50', **kwargs)

Connect to Vivace using SSH.

Parameters
Returns

Return type

fabric.connection.Connection

Raises

RuntimeError – if the Python module fabric is not found

vivace.utils.ssh_download(remote_filename, local_filename=None, address='192.168.42.50')

Copy a file from Vivace to the local computer.

Parameters
  • remote_filename (str) –

  • local_filename (str, optional) –

  • address (str, optional) – IP address or hostname of Vivace

Returns

Return type

fabric.transfer.Result

Raises

RuntimeError – if the Python module fabric is not found

vivace.utils.ssh_execute(command, address='192.168.42.50')

Execute a command on Vivace.

Parameters
  • command (str) –

  • address (str, optional) – IP address or hostname of Vivace

Returns

Return type

fabric.runners.Result

Raises

RuntimeError – if the Python module fabric is not found

vivace.utils.ssh_reboot(address='192.168.42.50')

Reboot the Linux system on Vivace.

It is equivalent to ssh_execute(“/sbin/shutdown -r now”).

Parameters

address (str, optional) – IP address or hostname of Vivace

Returns

Return type

fabric.runners.Result

Raises

RuntimeError – if the Python module fabric is not found

vivace.utils.ssh_upload(local_filename, remote_filename=None, address='192.168.42.50')

Copy a file from the local computer to Vivace.

Parameters
  • local_filename (str) –

  • remote_filename (str, optional) –

  • address (str, optional) – IP address or hostname of Vivace

Returns

Return type

fabric.transfer.Result

Raises

RuntimeError – if the Python module fabric is not found

vivace.utils.templates_for_IQ_readout(frequency, duration, phase_corr=0.0, scale_I=1.0, scale_Q=1.0)

Calculate input templates to perform digital IQ demodulation.

Parameters
  • frequency (float) – Demodulation frequency \(f\) in Hz. Valid range is [0.0, 2.0e+9).

  • duration (float) – Demodulation window in seconds. Will be rounded to multiples of 250 ps.

  • phase_corr (float, optional) – \(\phi\)

  • scale_I (float, optional) – \(A_I\)

  • scale_Q (float, optional) – \(A_Q\)

Returns

  • templateI (np.ndarray of np.float64) – \(T_I\)

  • templateQ (np.ndarray of np.float64) – \(T_Q\)

Notes

The two generated templates are given by

\(T_I = A_I \cos(2\pi f t + \phi)\)

\(T_Q = -A_Q \sin(2\pi f t + \phi)\)

vivace.utils.triangle(nr_samples)

Create a triangular envelope/template.

Parameters

nr_samples (int) –

Returns

Return type

np.ndarray of np.float64

vivace.utils.untwist_downconversion(I_port, Q_port)

Convert a measured IQ pair into a low/high sideband pair.

Parameters
  • I_port (np.ndarray of np.complex128) –

  • Q_port (np.ndarray of np.complex128) –

Returns

  • L_sideband (np.ndarray of np.complex128)

  • H_sideband (np.ndarray of np.complex128)

Notes

This function follows the convention used in Vivace’s digital mixers. When using external mixers, a different convention might be used. Check with the mixer vendor, or test.


version module

Version information.

vivace.version.get_variant_firmware(viv)

Variant/type of the loaded firmware.

Parameters

viv (Pulsed or DirectLockin) – Instance of Vivace.

Returns

variant

Return type

int

vivace.version.get_version_all(viv)

Summary of all versions as a formatted string.

Parameters

viv (Pulsed or DirectLockin) – Instance of Vivace.

Returns

version

Return type

str

vivace.version.get_version_api(viv=None)

Version of the public API.

Parameters

viv (Pulsed or DirectLockin, optional) – Instance of Vivace.

Returns

version

Return type

str

vivace.version.get_version_clock(viv)

Version of the clock-configuration program.

Parameters

viv (Pulsed or DirectLockin) – Instance of Vivace.

Returns

version

Return type

str

vivace.version.get_version_firmware(viv)

Version of the loaded firmware.

Parameters

viv (Pulsed or DirectLockin) – Instance of Vivace.

Returns

version

Return type

int

vivace.version.get_version_server(viv)

Version of the Linux server.

Parameters

viv (Pulsed or DirectLockin) – Instance of Vivace.

Returns

version

Return type

str