utils module¶
Collection of functions that might be useful, or might not.
- class presto.utils.ProgressBar(size, update_time=1.0)¶
Bases:
object
Prints a progress bar to stderr, keeping track of remaining time.
- Parameters:
Example
>>> pb = ProgressBar(100) >>> pb.start() >>> for _ in range(100): >>> time.sleep(0.1) # <-- do work here! >>> pb.increment() >>> pb.done()
- done()¶
Terminate the progress bar and print total time.
- increment(inc=1)¶
Increment the progress bar.
Will not change the text on stderr if too little time has passed since last update.
- Parameters:
inc (
int
) – how many “units of work” have been done since last call
- start()¶
Start counting time.
- class presto.utils.Spinner(msg, quiet=False)¶
Bases:
object
Prints a spinner to stderr, while some work is being done.
- Parameters:
Example
Using a context manager (
with
block):>>> with Spinner("Doing lots of work") >>> time.sleep(3.14) # <-- do work here!
Will print sequentially (all in one line):
Doing lots of work... - Doing lots of work... / Doing lots of work... | Doing lots of work... \ Doing lots of work... - Doing lots of work... / ... Doing lots of work: 3.2s
- presto.utils.as_flat_list(x)¶
Return
x
as a flat unidimensional list.
- presto.utils.format_precision(n, s)¶
Format a value and uncertainty to the correct number of significant digits.
- Parameters:
- Return type:
- Returns:
a formatted string with numbers rounded to significant digits.
Examples
>>> format_precision(36.91226461435421, 0.4060358649863922) '36.9 ± 0.4'
- presto.utils.format_sec(s)¶
Format a time interval in seconds into a more human-readable string.
- Parameters:
- Return type:
- Returns:
time interval in the form “Xh Ym Z.zs”.
Examples
>>> format_sec(np.pi * 1e+8) '9y 348d 20h 27m 45.4s' >>> format_sec(np.exp(-10)) '45.4us'
- presto.utils.get_sourcecode(script_filename)¶
Open a file and return its content.
- presto.utils.newman_phases(n)¶
Calculate phases for a frequency comb with low crest factor.
- Parameters:
n (
int
) – the number of tones/components in the frequency comb- Return type:
- Returns:
an array of phases in radians with length
n
Notes
The individual tones/components of the comb are assumed to be equally spaced in frequency.
The returned phases are computed using the method by [Newman1965] as reported by [Boyd1986]: \(\phi_k = \pi k^2 / n\) for \(k = 0, ..., n-1\).
See also
References
[Newman1965]– D. J. Newman, “An L1 extremal problem for polynomials”, Proceedings of the American Mathematical Society 16(6), 1287-1290 (1965).
[Boyd1986]– S. Boyd, “Multitone signals with low crest factor”, IEEE Transactions on Circuits and Systems 33(10), 1018-1022 (1986).
Examples
Set up a frequency comb with 100 tones starting at 100 MHz and separated by 10 kHz, using Newman phases and maximum (full-scale) amplitude.
Using
lockin
mode:>>> import numpy as np >>> >>> from presto.lockin import Lockin >>> from presto.utils import newman_phases, newman_scale >>> >>> N = 100 # number of tones in frequency comb >>> AMP = 1.0 # full-scale amplitude >>> OFFSET = 100e6 # starting frequency of comb >>> DELTA = 10e3 # frequency separation inside comb >>> OUT_PORT = 1 >>> >>> with Lockin() as lck: >>> freqs = OFFSET + DELTA * np.arange(N) >>> amps = np.full(N, AMP / newman_scale(N)) >>> phases = newman_phases(N) >>> >>> lck.set_df(DELTA) >>> og = lck.add_output_group(OUT_PORT, N) >>> og.set_frequencies(freqs).set_phases(phases).set_amplitudes(amps) >>> lck.apply_settings()
Using
spectral
mode:>>> import numpy as np >>> >>> from presto.spectral import Spectral >>> from presto.utils import newman_phases, newman_scale >>> >>> N = 100 # number of tones in frequency comb >>> AMP = 1.0 # full-scale amplitude >>> OFFSET = 100e6 # starting frequency of comb >>> DELTA = 10e3 # frequency separation inside comb >>> OUT_PORT = 1 >>> >>> with Spectral() as spec: >>> freqs = OFFSET + DELTA * np.arange(N) >>> amps = np.full(N, AMP / newman_scale(N)) >>> phases = newman_phases(N) >>> >>> period = 1.0 / DELTA >>> spec.output_multicos(OUT_PORT, period, freqs, amps, phases) >>> # ... measure here ...
- presto.utils.newman_scale(n)¶
Global amplitude-scaling factor for a frequency comb using Newman phases.
Divide the maximum amplitude of the comb by this factor to ensure that the output is not clipped due to the crest factor.
- Parameters:
n (
int
) – the number of tones/components in the frequency comb- Return type:
float64
See also
- presto.utils.plot_sequence(pls, period=None, repeat_count=1, num_averages=1)¶
Plots pulse sequence for interactive inspection.
See Plot pulse sequences for more documentation.
- Parameters:
pls (pulsed.Pulsed) – Pulsed object that contains the pulse sequence to be plotted.
period (
Optional
[float
]) – Measurement time in seconds for one repetition. Must be a multiple ofget_clk_T()
repeat_count (int or tuple of ints) – Number of times to repeat the experiment and stack the acquired data (no averaging). For multi-dimensional parameter sweeps,
repeat_count
is a tuple where each element specifies the number of repetitions along that axis.num_averages (
int
) – Number of times to repeat the whole sequence (including the repetitions due torepeat_count
) and average the acquired data.
- Returns:
The matplotlib Figure instance.
- Return type:
Examples
>>> from presto import pulsed >>> from presto.utils import plot_sequence, sin2 >>> >>> with pulsed.Pulsed(dry_run=True) as pls: >>> # define the pulse and set parameters >>> pulse = pls.setup_template(1, 0, 0.5 * sin2(100)) >>> pls.setup_scale_lut(1, 0, 0.707) >>> pls.set_store_ports(1) >>> pls.set_store_duration(100e-9) >>> >>> # define the pulse sequence >>> pls.store(0.0) >>> pls.output_pulse(26e-9, pulse) >>> >>> # plot the pulse sequence >>> plot_sequence(pls)
- Raises:
ImportError – if
matplotlib
is not installed.
- presto.utils.recommended_dac_config(freq, *, print_all=False, plot=False)¶
Recommended DAC configuration.
- Parameters:
freq (
float
) – signal frequency in Hzprint_all (
bool
) – set toTrue
to print all valid DAC configurations forfreq
, together with frequency of spurious tones and suggested reconstruction filtersplot (
bool
) – set toTrue
to show amatplotlib
figure with DAC zones and frequencies of signal and spurious tones
- Returns:
A tuple of
(dac_mode, dac_fsample)
wheredac_mode
(hardware.DacFSample
)dac_fsample
(hardware.DacMode
)
represent the most recommended DAC configuration.
- Raises:
ValueError – if
freq
is negative or above 9.6 GHz.
Examples
Print detailed information:
>>> recommended_dac_config(5.2e9, print_all=True) Valid DAC configurations for signal at 5200.0 MHz: * Mixed42-G8 (score 1680): - low-frequency spur: 2800.0 MHz - high-frequency spur: 10800.0 MHz - compatible band-pass filters: ['VBFZ-5500-S+', 'ZBSS-6G-S+', 'ZVBP-5G-S+'] * Mixed02-G6 (score 1173): - low-frequency spur: 800.0 MHz - high-frequency spur: 6800.0 MHz - compatible band-pass filters: ['ZVBP-5G-S+']
Use suggested configuration directly:
>>> dac_mode, dac_fsample = recommended_dac_config(5.2e9) >>> print(f"Best DacMode is {dac_mode.name}, DacFSample is {dac_fsample.name}") DacMode is Mixed42, DacFSample is G8 >>> from presto import lockin, pulsed >>> lck = lockin.Lockin(dac_mode=dac_mode, dac_fsample=dac_fsample) >>> pls = pulsed.Pulsed(dac_mode=dac_mode, dac_fsample=dac_fsample)
- presto.utils.rotate_opt(data, return_x=False)¶
Rotates
data
so that all the signal is in the I quadrature (real part).
- presto.utils.si_prefix_scale(data)¶
Calculare the appropriate SI prefix for
data
.- Parameters:
data – an integer, a float, a list or array of those, …
- Return type:
- Returns:
a tuple (prefix, scale)
Examples
>>> si_prefix_scale(3.1415e-5) ('μ', 1000000)
>>> value = 2.718e-7 >>> (unit, scale) = si_prefix_scale(value) >>> print(f"The length is {scale * value} {unit}m") The length is 271.8 nm
- presto.utils.sin2(nr_samples, drag=0.0)¶
Create a \(\sin^2\) envelope/template.
- presto.utils.sinP(P, nr_samples)¶
Create a \(\sin^P\) envelope/template.
- presto.utils.ssh_reboot(address)¶
Reboot the Linux system on the hardware.
Establish an SSH connection to
address
and perform a full reboot the system, roughly equivalent to the commandsystemctl reboot
. The system should be back online after about one minute.To instead restart only the service running on the system, see
ssh_restart()
.- Parameters:
address (
str
) – IP address or hostname of the hardware
Note
Requires Python package paramiko to be installed.
- Raises:
ImportError – Python module
paramiko
not found.
- presto.utils.ssh_restart(address)¶
Restart the service running on the hardware.
Establish an SSH connection to
address
and perform a soft restart of the service, roughly equivalent tosystemctl restart <service-name>
. The service should be back online immediately.To instead perform a full reboot of the Linux system, see
ssh_reboot()
.- Parameters:
address (
str
) – IP address or hostname of the hardware
Note
Requires Python package paramiko to be installed.
- Raises:
ImportError – Python module
paramiko
not found.
- presto.utils.to_pm_pi(phase)¶
Converts a phase in radians into the [-π, +π) interval.
- presto.utils.triangle(nr_samples)¶
Create a triangular envelope/template.
- presto.utils.untwist_downconversion(I_port, Q_port)¶
Convert a measured IQ pair into a low/high sideband pair.