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:
  • size (int) – how many “units of work” will be done

  • update_time (float) – limit the update of the progress bar to update_time seconds

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.

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

Return type:

list

Returns:

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

presto.utils.format_precision(n, s)

Format a value and uncertainty to the correct number of significant digits.

Parameters:
  • n (float) – nominal value.

  • s (float) – uncertainty.

Return type:

str

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:

s (Union[float, timedelta]) – time interval in seconds.

Return type:

str

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.

Parameters:

script_filename (str) – path to the file.

Return type:

List[str]

Returns:

the lines of the file at script_filename.

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 of get_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 to repeat_count) and average the acquired data.

Returns:

The matplotlib Figure instance.

Return type:

matplotlib.figure.Figure

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 Hz

  • print_all (bool) – set to True to print all valid DAC configurations for freq, together with frequency of spurious tones and suggested reconstruction filters

  • plot (bool) – set to True to show a matplotlib figure with DAC zones and frequencies of signal and spurious tones

Returns:

A tuple of (dac_mode, dac_fsample) where

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

Parameters:
  • data (ndarray[Any, dtype[complex128]]) – dtype should be complex128.

  • return_x (bool) – if True, return also the angle by which data was rotated.

Return type:

Union[ndarray[Any, dtype[complex128]], Tuple[ndarray, float]]

Returns:

data * np.exp(1j * x), with x such that np.std(ret.imag) is minimum. dtype=complex128.

If return_x=True, also return the angle x.

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:

Tuple[str, float]

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.

Parameters:
  • nr_samples (int)

  • drag (float) – if nonzero, use DRAG with \(\lambda / \alpha\) equal to drag

Return type:

ndarray

Returns:

NumPy array for desired pulse with dtype=float64 if drag=0.0, or dtype=complex128 otherwise.

presto.utils.sinP(P, nr_samples)

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

Parameters:
Return type:

ndarray

Returns:

NumPy array for desired pulse with dtype=float64.

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 command systemctl 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 to systemctl 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.

Parameters:

phase (float)

Return type:

float

presto.utils.triangle(nr_samples)

Create a triangular envelope/template.

Parameters:

nr_samples (int)

Return type:

ndarray

Returns:

NumPy array for desired pulse with dtype=float64.

presto.utils.untwist_downconversion(I_port, Q_port)

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

Parameters:
  • I_port (ndarray) – dtype=complex128

  • Q_port (ndarray) – dtype=complex128

Return type:

Tuple[ndarray, ndarray]

Returns:

a tuple (L_sideband, H_sideband) of NumPy arrays with dtype=complex128.