waveforms#

Module containing helper functions related to waveforms.

Module Contents#

Classes#

GetWaveformPartial

Protocol type definition class for the get_waveform partial function.

Functions#

get_waveform_size(→ int)

Return the number of samples required to respect the granularity.

resize_waveforms(→ None)

Resizes the waveforms to a multiple of the given granularity.

resize_waveform(→ numpy.ndarray)

Return the waveform in a size that is a modulo of the given granularity.

shift_waveform(→ Tuple[int, numpy.ndarray])

Return the waveform shifted with a number of samples.

get_waveform(→ numpy.ndarray)

Return the waveform of a pulse_info dictionary.

get_waveform_by_pulseid(→ Dict[int, GetWaveformPartial])

Return a lookup dictionary of pulse_id and its partial waveform function.

exec_waveform_partial(→ numpy.ndarray)

Return the result of the partial waveform function.

exec_waveform_function(→ numpy.ndarray)

Return the result of the pulse's waveform function.

exec_custom_waveform_function(→ numpy.ndarray)

Load and import an ambiguous waveform function from a module by string.

apply_mixer_skewness_corrections(→ numpy.ndarray)

Apply a correction for amplitude imbalances and phase errors.

modulate_waveform(→ numpy.ndarray)

Generate a (single sideband) modulated waveform from a given envelope.

normalize_waveform_data(→ Tuple[numpy.ndarray, float, ...)

Normalize waveform data, such that the value is +1.0 where the absolute value is

area_pulses(→ float)

Calculate the area of a set of pulses.

area_pulse(→ float)

Calculate the area of a single pulse.

class GetWaveformPartial[source]#

Bases: Protocol

Protocol type definition class for the get_waveform partial function.

get_waveform_size(waveform: numpy.ndarray, granularity: int) int[source]#

Return the number of samples required to respect the granularity.

Parameters:
  • waveform – Numerical waveform.

  • granularity – The granularity.

resize_waveforms(waveforms_dict: Dict[int, numpy.ndarray], granularity: int) None[source]#

Resizes the waveforms to a multiple of the given granularity.

Parameters:
  • waveforms_dict – The waveforms dictionary.

  • granularity – The granularity.

resize_waveform(waveform: numpy.ndarray, granularity: int) numpy.ndarray[source]#

Return the waveform in a size that is a modulo of the given granularity.

Parameters:
  • waveform – The waveform array.

  • granularity – The waveform granularity.

Returns:

The resized waveform with a length equal to mod(len(waveform), granularity) == 0.

shift_waveform(waveform: numpy.ndarray, start_in_seconds: float, sampling_rate: int, resolution: int) Tuple[int, numpy.ndarray][source]#

Return the waveform shifted with a number of samples.

This compensates for rounding errors that cause misalignment of the waveform in the clock time domain.

Note

when using this method be sure that the pulse starts at a round(start_in_sequencer_count).

waveform = np.ones(32)
sampling_rate = int(2.4e9)
resolution: int = 8

t0: float = 16e-9
#                 4.8 = 16e-9 / (8 / 2.4e9)
start_in_sequencer_count = (t0 // (resolution / sampling_rate))

start_waveform_at_sequencer_count(start_in_sequencer_count, waveform)
Parameters:
  • waveform – The waveform.

  • start_in_seconds – The start time (in seconds).

  • sampling_rate – The sampling rate

  • resolution – The sequencer resolution.

get_waveform(pulse_info: Dict[str, Any], sampling_rate: float) numpy.ndarray[source]#

Return the waveform of a pulse_info dictionary.

Parameters:
  • pulse_info – The pulse_info dictionary.

  • sampling_rate – The sample rate of the waveform.

Returns:

The waveform.

get_waveform_by_pulseid(schedule: quantify_scheduler.schedules.schedule.Schedule) Dict[int, GetWaveformPartial][source]#

Return a lookup dictionary of pulse_id and its partial waveform function.

The keys are pulse info ids while the values are partial functions. Executing the waveform will return a numpy.ndarray.

Parameters:

schedule – The schedule.

exec_waveform_partial(pulse_id: int, pulseid_waveformfn_dict: Dict[int, GetWaveformPartial], sampling_rate: int) numpy.ndarray[source]#

Return the result of the partial waveform function.

Parameters:
  • pulse_id – The pulse uuid.

  • pulseid_waveformfn_dict – The partial waveform lookup dictionary.

  • sampling_rate – The sampling rate.

Returns:

The waveform array.

exec_waveform_function(wf_func: str, t: numpy.ndarray, pulse_info: dict) numpy.ndarray[source]#

Return the result of the pulse’s waveform function.

If the wf_func is defined outside quantify-scheduler then the wf_func is dynamically loaded and executed using exec_custom_waveform_function().

Parameters:
  • wf_func – The custom waveform function path.

  • t – The linear timespace.

  • pulse_info – The dictionary containing pulse information.

Returns:

Returns the computed waveform.

exec_custom_waveform_function(wf_func: str, t: numpy.ndarray, pulse_info: dict) numpy.ndarray[source]#

Load and import an ambiguous waveform function from a module by string.

The parameters of the dynamically loaded wf_func are extracted using inspect.signature() while the values are extracted from the pulse_info dictionary.

Parameters:
  • wf_func – The custom waveform function path.

  • t – The linear timespace.

  • pulse_info – The dictionary containing pulse information.

Returns:

Returns the computed waveform.

apply_mixer_skewness_corrections(waveform: numpy.ndarray, amplitude_ratio: float, phase_shift: float) numpy.ndarray[source]#

Apply a correction for amplitude imbalances and phase errors.

Using an IQ mixer from previously calibrated values.

Phase correction is done using:

\[Re(z_{corrected}) (t) = Re(z (t)) + Im(z (t)) \tan(\phi) Im(z_{corrected}) (t) = Im(z (t)) / \cos(\phi)\]

The amplitude correction is achieved by rescaling the waveforms back to their original amplitudes and multiplying or dividing the I and Q signals respectively by the square root of the amplitude ratio.

Parameters:
  • waveform – The complex valued waveform on which the correction will be applied.

  • amplitude_ratio – The ratio between the amplitudes of I and Q that is used to correct for amplitude imbalances between the different paths in the IQ mixer.

  • phase_shift – The phase error (in deg) used to correct the phase between I and Q.

Returns:

The complex valued waveform with the applied phase and amplitude corrections.

modulate_waveform(t: numpy.ndarray, envelope: numpy.ndarray, freq: float, t0: float = 0) numpy.ndarray[source]#

Generate a (single sideband) modulated waveform from a given envelope.

This is done by multiplying it with a complex exponential.

\[z_{mod} (t) = z (t) \cdot e^{2\pi i f (t+t_0)}\]

The signs are chosen such that the frequencies follow the relation RF = LO + IF for LO, IF > 0.

Parameters:
  • t – A numpy array with time values

  • envelope – The complex-valued envelope of the modulated waveform

  • freq – The frequency of the modulation

  • t0 – Time offset for the modulation

Returns:

The modulated waveform

normalize_waveform_data(data: numpy.ndarray) Tuple[numpy.ndarray, float, float][source]#

Normalize waveform data, such that the value is +1.0 where the absolute value is maximal.

This means that two waveforms where waveform_1 = c * waveform_2 (c can be any real number) will be normalized to the same normalized waveform data; this holds separately for the real and imaginary parts.

Parameters:

data – The waveform data to rescale.

Returns:

  • rescaled_data – The rescaled data.

  • amp_real – The original amplitude of the real part.

  • amp_imag – The original amplitude of the imaginary part.

area_pulses(pulses: List[Dict[str, Any]], sampling_rate: float) float[source]#

Calculate the area of a set of pulses.

For details of the calculation see area_pulse.

Parameters:
  • pulses – List of dictionary with information of the pulses

  • sampling_rate – Sampling rate for the pulse

Returns:

The area formed by all the pulses

area_pulse(pulse: Dict[str, Any], sampling_rate: float) float[source]#

Calculate the area of a single pulse.

The sampled area is calculated, which means that the area calculated is based on the sampled waveform. This can differ slightly from the ideal area of the parameterized pulse.

The duration used for calculation is the duration of the pulse. This duration is equal to the duration of the sampled waveform for pulse durations that are integer multiples of the 1/sampling_rate.

Parameters:
  • pulse – The dictionary with information of the pulse

  • sampling_rate – Sampling rate for the pulse

Returns:

The area defined by the pulse