openqlab.analysis – Data Analysis Tools and Helpers

Note

This documentation is unfortunately very much incomplete. The modules documented below are fairly recent, but there is a lot of interesting old code, especially for use with covariance matrix calculations. Please have a look at the source code or old scripts for usage examples – and it would be nice if you could provide documentation afterwards.

Gaussian Beam

Fit beam data obtained from a beam analyzer to the gaussian beam model using non-linear least squares.

class openqlab.analysis.gaussian_beam.GaussianBeam(q: complex, wavelength: float)

Represents a Gaussian beam with a complex gaussian beam parameter q.

property divergence: float | ndarray

Beam divergence in radians.

classmethod from_waist(w0: float, z0: float, wavelength: float) GaussianBeam

Create Gaussian beam from waist size and position.

Parameters:
  • w0 (float) – Waist size in meters

  • z0 (float) – Waist position in meters

  • wavelength (float) – Wavelength in meters

get_profile(zpoints: Index | ndarray | float) ndarray | Index | float

Returns the beam width at points zpoints along the beam axis.

propagate(d)

Returns the beam parameter after free-space propagation of d

property w0: float | ndarray

Waist size in meters.

property wavelength: float | ndarray

Wavelength in m.

property z0: float | ndarray

The position of the beam waist on the z-axis in meters.

openqlab.analysis.gaussian_beam.fit_beam_data(data: DataFrame, wavelength: float, bounds: Tuple[List[float], List[float]] = ([0, -inf], [inf, inf]), guess_w0: float = 0.0003, guess_z0: float = 0.0, plot: bool = True, print_results: bool = True) DataContainer
Parameters:
  • data – Data to fit containing the position data in meters as index and the 1/e^2 (13%) radius in meters as columns for different beams.

  • wavelength – Wavelength of the light in m

  • bounds – Lower and upper bounds for the fit parameters in meters in the form ([w0_lower,z0_lower],[w0_upper,z0_upper]).

  • guess_w0 – Initial estimate of the beam waist in meters.

  • guess_z0 – Initial estimate of the waist position in meters.

  • plot – Create plot after fitting.

  • print_results – Print results in a human readable form.

Returns:

Fit results with errors

Return type:

Dataframe

Cavity

Cavity calculations

Automatically calculate cavity parameters with data taken from an oscilloscope.

openqlab.analysis.cavity.finesse(data: Series, plot: bool = True, offset: float | None = None, ax: Axes | None = None) List[float]

Finesse calculation using a cavity scan.

Parameters:
  • data (Series) – Data is the amplitude column with two main modes.

  • plot (bool) – Plot is giving out a plot to make sure the algorithm has found the correct points.

  • offset (Optional[float]) – Manually set the offset, to not use the median value.

  • (Axes (ax) – Provide an Axes for advanced figures.

  • optional) – Provide an Axes for advanced figures.

Returns:

Calculated finesse for both peaks.

Return type:

list(float)

openqlab.analysis.cavity.modematching(data: Series, plot: bool = False, U_max: float | None = None, offset: float | None = None, rel_prominence: float = 0.02, without_main_peaks: bool = False, ax: Axes | None = None) float

Calculate the mode matching.

It assumes a cavity scan bounded by two peaks of the main mode. The method looks for the smaller peaks where the detection threshold can be adjusted with rel_prominence.

Offset

The default method to find out the offset is by calculating the mean value. If you have measured it more precisely, use the parameter offset.

Improve precision

To get a better resolution for small peaks there is an option to take data with a clipped main mode. Use the parameter U_max to manually set the measured maximum value.

Parameters:
  • data (Series) – Measured data (just one column).

  • plot (bool) – Make a plot to see, if the correct peaks where detected.

  • U_max (Optional[float]) – U_max is the parameter to set the peak voltage of the cropped main peaks. If set, it is assumed that the main peaks are not in the data.

  • rel_prominence (float) – rel_prominence is the parameter to adjust the threshold for the detection of small peaks.

  • without_main_peaks (bool) – Deprecated! Is assumed if U_max is set.

  • (Axes (ax) – Provide an Axes for advanced figures.

  • optional) – Provide an Axes for advanced figures.

Returns:

Calculated mode matching value.

Return type:

float

Phase

Phase calculations

Phase module for calculations regarding the phase.

openqlab.analysis.phase.accumulated_phase(data: Series, limit: float = 340) None

Scan a row of a pandas.DataFrame and calculate the absolute phase delay.

Looks for a jump in the phase of at least limit and adds ±360° to remove the phase jump.

Parameters:
Returns:

The row is changed inplace, no need for a return value.

Return type:

None

openqlab.analysis.phase.clamp_phase(phase: float | Series | DataFrame) float | Series | DataFrame

Returns phase with all values mapped to between +/- 180 degrees.

Servo Design

Toolkit for simulating and designing servo controllers.

openqlab.ServoDesign helps with designing a standard servo circuit.

class openqlab.analysis.servo_design.Differentiator(corner_frequency: float, second_parameter: float | None = None, enabled: bool = True)

Create a differentiator with corner frequency corner_frequency, compensated for unity gain at low frequencies.

Parameters:
  • corner_frequency (float) – The corner frequency.

  • sF (float, optional) – Frequency were the ~f slope stops, defaults to 10 * corner_frequency.

calculate() Tuple[float, float, float]

Calculate must be implemented by the specific filter class.

It should recalculate the zpk and return it.

Return type:

z, p, k

class openqlab.analysis.servo_design.Filter(corner_frequency: float, second_parameter: float | None = None, enabled: bool = True)

A container for a second-order analog filter section. Poles and zeros are in units of Hz.

Parameters:
  • description (str) – A short description of this filter section

  • z (array-like) – A zero or list of zeros

  • p (array-like) – A pole or list of poles

  • k (float) – Gain

abstract calculate()

Calculate must be implemented by the specific filter class.

It should recalculate the zpk and return it.

Return type:

z, p, k

discrete_SOS(sampling_frequency: float) ndarray

Return a discrete-time second order section of this filter, with sampling frequency sampling_frequency.

discrete_zpk(sampling_frequency: float) Tuple[ndarray, ndarray, float]

Return the discrete-time transfer function of this filter, evaluated for a sampling frequency of sampling_frequency.

class openqlab.analysis.servo_design.Integrator(corner_frequency: float, second_parameter: float | None = None, enabled: bool = True)

Create an integrator with corner frequency ‘corner_frequency’, compensated for unity gain at high frequencies.

Parameters:
  • corner_frequency (float) – The corner frequency.

  • sF (float, optional) – Frequency were the ~1/f slope starts, defaults to 0.001 * corner_frequency.

calculate() Tuple[float, float, float]

Calculate must be implemented by the specific filter class.

It should recalculate the zpk and return it.

Return type:

z, p, k

class openqlab.analysis.servo_design.Lowpass(corner_frequency: float, second_parameter: float = 0.707, enabled: bool = True)

Create a 2nd-order lowpass filter with variable quality factor second_parameter (might be referenced as Q in the description).

The default second_parameter of 1/sqrt(2) results in a Butterworth filter with flat passband.

Parameters:

corner_frequency (float) – The corner frequency.

calculate() Tuple[List[Any], List[complex], float]

Calculate must be implemented by the specific filter class.

It should recalculate the zpk and return it.

Return type:

z, p, k

class openqlab.analysis.servo_design.Notch(corner_frequency: float, second_parameter: float = 1, enabled: bool = True)

Create a notch filter at frequency corner_frequency with a quality factor second_parameter, where the -3dB filter bandwidth bw is given by second_parameter = corner_frequency/bw.

Parameters:
  • corner_frequency (float) – Frequency to remove from the spectrum

  • second_parameter (float) – Quality factor of the notch filter. Defaults to 1. Referenced as Q in description.

calculate() Tuple[List[complex], List[complex], float]

Calculate must be implemented by the specific filter class.

It should recalculate the zpk and return it.

Return type:

z, p, k

class openqlab.analysis.servo_design.ServoDesign

A Servo (controller) design class.

Current purpose is mainly filter handling and should be used as follows:

The object itself holds a set of (currently maximum) 5 filters. Filter types can be defined as new subclasses to the Filter class.

The FILTER UTILITY section contains all methods handling filter operations, including clear and read. Filters should be added using either ‘add’ or ‘addIndexed’. Normal ‘add’ will simply append the filter to the list and fail when the list is fullself. ‘addIndexed’ however will overwrite the the filter at the current position and fail in case an index out of range was specified.

differentiator(corner_frequency: float, fstop: float | None = None, enabled: bool = True) None

Add a differentiator with corner frequency corner_frequency, compensated for unity gain at low frequencies.

Parameters:
  • corner_frequency (float) – The corner frequency.

  • fstop (float, optional) – Frequency were the ~f slope stops, defaults to 1000 * corner_frequency.

discrete_form(sampling_frequency: float = 200000.0, fs: float | None = None) Dict[str, float | List[Dict[str, str | ndarray | bool | float]]]

Convert the servo and its filters to a digital, discrete-time representation in terms of second-order sections at a sampling frequency of sampling_frequency.

Returns:

a list containing a dict for each filter with additional information.

Return type:

list

property filters: Sequence[Filter | None]

Return the global class field filterListself.

Returns:

filterList – The global field containing a list of available filters.

Return type:

list

integrator(corner_frequency: float, fstop: float | None = None, enabled: bool = True) None

Add an integrator with corner frequency corner_frequency, compensated for unity gain at high frequencies.

Parameters:
  • corner_frequency (float) – The corner frequency.

  • fstop (float, optional) – Frequency were the ~1/f slope starts, defaults to 0.001 * corner_frequency.

is_empty() bool

Check whether ServoDesign contains any filter.

log_gain(gain: float) None

Add gain specified in dB (amplitude scale, i.e. 6dB is a factor of 2).

Parameters:

gain (float) – Gain that should be added

lowpass(corner_frequency: float, second_parameter: float = 0.707, enabled: bool = True) None

Add a 2nd-order lowpass filter with variable quality factor second_parameter.

The default second_parameter of 1/sqrt(2) results in a Butterworth filter with flat passband.

Parameters:

parameter (type) – parameter description

notch(corner_frequency: float, second_parameter: float = 1, enabled: bool = True) None

Add a notch filter at frequency corner_frequency with a quality factor second_parameter, where the -3dB filter bandwidth bw is given by second_parameter = corner_frequency/bw.

Parameters:
  • corner_frequency (float) – Frequency to remove from the spectrum

  • second_parameter (float) – Quality factor of the notch filter

Returns:

the servo object with added notch filter

Return type:

Servo

property plant

Set the system that the servo should control (usually called the plant), which needs to be given as a pandas.DataFrame containing two columns with amplitude and phase frequency response. The index is assumed to contain the frequencies.

plot(freq: ndarray | None = None, plot: bool = True, correct_latency: bool | float = False, **kwargs) Figure | DataFrame

Plot the servo response over the frequencies given in freq.

If a plant was set for this servo, then freq is ignored and the frequency list from the plant is used instead. If both plant and freq are None, a list is created from [0,…,10]kHz using numpy.logspace.

Parameters:
  • freq (numpy.ndarray) – frequencies for plotting calculation. Default is 1 to 1e5, with 1000 steps.

  • plot (bool) – returns a DataFrame if False. Defaults to True

  • correct_latency (bool or float) – If the data has been taken piping through ADwin an extra phase has been added. This can be corrected by giving ADwins sample rate (Default 200 kHz).

  • **kwargs – Parameters are passed to the pandas.DataFrame.plot method

Returns:

Retuns a DataFrame or a plot

Return type:

matplotlib.figure.Figure or pandas.DataFrame

zpk() Tuple[ndarray, ndarray, float]

Return combined zeros, poles and gain for all filters.

Returns:

  • zeros (numpy.ndarray) – The zeros of the combined servo

  • poles (numpy.ndarray) – The poles of the combined servo

  • gain (float) – Gain of the combined servo

Squeezing

Simple squeezing calculations.

openqlab.analysis.squeezing.initial(sqz: float | list | ndarray | ufloat, anti_sqz: float | list | ndarray | ufloat)

Calculate the initial squeezing level from known squeezing and anti-squeezing levels.

Parameters:
  • sqz (float, numpy.array) – The squeezing level (negative value, because it is below vacuum).

  • anti_sqz (float, numpy.array) – The anti-squeezing level (positive value, because it is above vacuum).

openqlab.analysis.squeezing.losses(sqz: float | list | ndarray | ufloat, anti_sqz: float | list | ndarray | ufloat)

Calculate losses from known squeezing and anti-squeezing levels.

Parameters:
  • sqz (float, numpy.array) – The squeezing level (negative value, because it is below vacuum).

  • anti_sqz (float, numpy.array) – The anti-squeezing level (positive value, because it is above vacuum).

openqlab.analysis.squeezing.max(loss: float | list | ndarray | ufloat, initial: float | list | ndarray | ufloat = -20, antisqz: bool = False)

Calculate the maximum possible squeezing level with given loss.

Parameters:
  • loss (float, numpy.array) – Level of losses (number, relative to 1).

  • initial (float, numpy.array) – Initial squeezing level.

  • antisqz (bool) – Include antisqueezing in the result: [sqz, antisqz] or as list of arrays, if loss is an array.