# lockin module¶

Continuous-wave generation and measurement.

Detailed information is provided in the documentation for each class.

 Lockin Use the hardware in continuous-wave mode. InputGroup Settings of a lock-in input group. OutputGroup Settings of a lock-in output group.

Converter modes (re-exported from hardware module):

class presto.lockin.AdcMode(value)

Configuration for analog-to-digital converters (ADC), i.e. input channels

See AdcMode for full documentation

class presto.lockin.DacMode(value)

Configuration for digital-to-analog converters (DAC), i.e. output channels

See DacMode for full documentation

Converter sampling rates (re-exported from hardware module):

class presto.lockin.AdcFSample(value)

Sampling rate setting for analog-to-digital converters (ADC), i.e. input channels

See AdcFSample for full documentation

class presto.lockin.DacFSample(value)

Sampling rate setting for digital-to-analog converters (DAC), i.e. output channels

See DacFSample for full documentation

## Lockin class¶

class presto.lockin.Lockin(*, ext_ref_clk=False, force_reload=False, dry_run=False, address=None, port=None, adc_mode=<AdcMode.Direct: 0>, adc_fsample=<AdcFSample.G2: 0>, dac_mode=<DacMode.Direct: 0>, dac_fsample=<DacFSample.G4: 1>)

Use the hardware in continuous-wave mode.

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 (optional) – if None or False use internal reference clock; if True use external reference clock (10 MHz); if float or int use external reference clock at ext_ref_clk Hz

• force_reload (bool, optional) – if True re-configure clock and reload 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 the hardware. If None, use factory default “192.168.42.50”.

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

• adc_mode (hardware.AdcMode or list, optional) – configure the inputs to sample in direct mode (default), or to use the digital mixers for downconversion. See Notes.

• adc_fsample (hardware.AdcFSample or list, optional) – configure the inputs sampling rate (default 2 GS/s). See Notes.

• dac_mode (hardware.DacMode or list, optional) – configure the outputs to work in direct mode (default), to use the digital mixers for upconversion. See Notes.

• dac_fsample (hardware.DacFSample or list, optional) – configure the outputs sampling rate (default 4 GS/s). See Notes.

Raises

ValueError – if adc_mode or dac_mode are not valid Converter modes; if adc_fsample or dac_fsample are not valid Converter rates.

Notes

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

For valid values of adc_mode and dac_mode, see Converter modes. For valid values of adc_fsample and dac_fsample, see Converter rates. For advanced configuration, e.g. different converter rates on different ports, see Advanced tile configuration.

add_input_group(port, nr_freq)presto.lockin.InputGroup

Create and return a new input group

Parameters
• port (int) – which input port the group should sample data from

• nr_freq (int) – how many frequencies the input group should demodulate

Returns

Return type

InputGroup

add_output_group(ports, nr_freq)presto.lockin.OutputGroup

Create and return a new output group

Parameters
• ports (int or list of int) – which output port(s) the group should output data to. If a list, the output will be replicated on all ports

• nr_freq (int) – how many frequencies the output group should modulate

Returns

Return type

OutputGroup

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.

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

get_clk_T()

Period of the programmable-logic clock in seconds.

Returns

Return type

float

get_clk_f()

Frequency of the programmable-logic clock in Hz.

Returns

Return type

float

get_df()

Get measurement bandwidth.

Returns

df – Measurement bandwith in Hz.

Return type

float

get_fs(which)

Get sampling frequency for which converter.

Parameters

which (str) – “adc” for input and “dac” for output.

Returns

fs

Return type

float

Raises

ValueError – if which is unknown.

get_ns(which='adc')

Get number of samples per lock-in window.

The sampling rate divided by the measurement bandwidth.

Returns

ns

Return type

int

get_pixels(n)dict

Get lock-in packets (pixels) from the hardware.

Parameters

n (int) – the number of lock-in packets to measure.

Returns

• pixels (dict) – dictionary with key port and value tuple(freqs, pixels, pixels_q)

• port (int) – input port measured

• freqs (numpy.ndarray) – frequencies at which the lockin measurement was done. dtype is numpy.float64

• pixels (numpy.ndarray) – measured lock-in data in ratio of full-scale input. shape is (n, len(freqs)). dtype is numpy.complex128. When using digital downconversion (adc_mode is AdcMode.Mixed), these are the pixels of the I port of the digital mixer.

• pixels_q (numpy.ndarray) – only present when using digital downconversion (adc_mode is AdcMode.Mixed), these are the pixels of the Q port of the digital mixer.

Raises

RuntimeError – if apply_settings() was not called after changing some setting

Notes

This method locks execution until at least n measured packets are available.

Examples

>>> data = lck.get_pixels(1000)
>>> freqs, pixels = data[1]
>>> freqs.shape
(32,)
>>> pixels.shape
(1000, 32)

hardware

interface to hardware features common to all modes of operation

Type

Hardware

set_df(df)

Set measurement bandwith.

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

Parameters

df (float) – Measurement bandwith in Hz.

Notes

Non-tuned measurement bandwidths can’t be set in hardware. When passing a non-tuned df, the closest tuned value will be set in hardware. To avoid confusion, it is recommended to explicitly tune df before calling this method.

set_dither(state, output_ports)

Add pseudorandom noise to the generated output.

Can improve harmonic and intermodulation distortion when working with small output amplitudes.

The change is active immediately

Parameters
• state (bool) – if True, add pseudorandom noise to the output

• output_ports (int or list of int) – which output port(s) should be affected

tune(f, df)

Perform standard 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

tune_perfect

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).

Nonetheless, the difference between f_set and f_tuned is actually really small: the worst-case error is get_fs(“dac”)/2/2**48, on the order of a single microhertz ($$1 \mathrm{\mu Hz}$$)! For most common applications, the resulting Fourier leakage and the phase-reset glitches are well below the noise level. If however, this is not acceptable, see tune_perfect().

tune_perfect(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

tune

standard 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.

## Input and output groups¶

class presto.lockin.InputGroup(port, nr_freq, lockin)

Settings of a lock-in input group.

Used as return type by Lockin.add_input_group(). Contains access functions for changing the settings of this input group.

The lock-in input is divided into 16 groups. Each group is capable of demodulating 12 different quadratures, for a total of 192 demodulations (96 I/Q pairs). Each demodulator has a configurable frequency and phase. Each group can acquire data from a single (configurable) input port.

Warning

Do not instantiate this class directly! Call Lockin.add_input_group() to obtain a valid instance.

get_frequencies()

Get the lock-in input frequencies.

Returns

freqs – frequencies in Hz. dtype is numpy.float64

Return type

numpy.ndarray

get_phases(*, deg=False)

Get the lock-in input phases.

Parameters

deg (bool, optional) – if True, get the phases in degrees in [-180.0, +180.0]; if False (default) radians in [-π, +π].

Returns

phases – phases in rad/deg for each frequency. dtype is numpy.float64.

Return type

numpy.ndarray

set_frequencies(freqs)presto.lockin.InputGroup

Set the lock-in input frequencies.

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

Parameters

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

Returns

Return type

InputGroup

Notes

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

set_phases(phases, *, deg=False)presto.lockin.InputGroup

Set the lock-in input phases.

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

Parameters
• phases (float or array_like) – phases in rad/deg. If less than available number of frequencies, set the rest to zero. When using the digital mixers (adc_mode is AdcMode.Mixed), sets the phase of both the I and the Q port of the downconversion mixer.

• deg (bool, optional) – if True, set the phases in degrees in [-180.0, +180.0]; if False (default) radians in [-π, +π].

Returns

Return type

InputGroup

class presto.lockin.OutputGroup(ports, nr_freq, lockin)

Settings of a lock-in output group.

Used as return type by Lockin.add_output_group(). Contains access functions for changing the settings of this output group.

The lock-in output is divided into 16 groups. Each group is capable of driving tones at 12 different frequencies, for a total of 192 frequencies. Each tone has a configurable frequency, phase and amplitude. Each group can be output on one or more output ports.

Warning

Do not instantiate this class directly! Call Lockin.add_output_group() to obtain a valid instance.

get_amplitudes()

Get the lock-in output amplitudes.

Returns

amps – amplitudes for each frequency with +/- 1.0 being full scale. dtype is numpy.float64.

Return type

numpy.ndarray

get_frequencies()

Get the lock-in output frequencies.

Returns

freqs – frequencies in Hz. dtype is numpy.float64

Return type

numpy.ndarray

get_phases(*, deg=False)

Get the lock-in output phases.

Parameters

deg (bool, optional) – if True, get the phases in degrees in [-180.0, +180.0]; if False (default) radians in [-π, +π].

Returns

phases – phases in rad/deg for each frequency. dtype is numpy.float64.

Return type

numpy.ndarray

set_amplitudes(amps)presto.lockin.OutputGroup

Set the lock-in output amplitudes.

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

Parameters

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

Returns

Return type

OutputGroup

set_frequencies(freqs)presto.lockin.OutputGroup

Set the lock-in output frequencies.

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

Parameters

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

Returns

Return type

OutputGroup

Notes

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

set_phases(phases, phases_q=None, *, deg=False)presto.lockin.OutputGroup

Set the lock-in output phases.

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

Parameters
• phases (float or array_like) – phases in rad/deg. If less than available number of frequencies, set the rest to zero. When using the digital mixers (dac_mode is one of DacMode.Mixedxx), sets the phase of the I port of the upconversion mixer.

• phases_q (float or array_like, optional) – when using the digital mixers, sets the phase of the Q port of the upconversion mixer. In direct mode (dac_mode is DacMode.Direct), setting phases_q throws a ValueError exception.

• deg (bool, optional) – if True, set the phases in degrees in [-180.0, +180.0]; if False (default) radians in [-π, +π].

Returns

Return type

OutputGroup