Moku:Lab laser lock box implements a 2 cascaded direct form I second-order stages IIR filter. It has a fixed sampling rate at 31.25 MHz. The coefficients can be set by *set_custom_filter *function in pymoku or MATLAB API, or directly loaded on the iPad with a 6 by 2 (6 columns, 2 rows) array as the following:

s1 | b0.1 | b1.1 | b2.1 | a1.1 | a2.1 |

s2 | b0.2 | b1.2 | b2.2 | a1.2 | a2.2 |

Each ‘a’ coefficient must be a float in the range [-2.0, +2.0). ‘s’ coefficients are multiplied into each ‘b’ coefficient before being sent to the device. These products (sN x b0.N, sN x b1.N, sN x b2.N) must also fall in the range [-2.0, +2.0). Internally, the ‘a’ and ‘b’ coefficients are represented as signed 32-bit fixed-point numbers, with 30 fractional bits.

For example, we can use scipy package to generate the coefficients for a second order butterworth filter like the following. It returns the coefficients array that can be later used in the *set_custom_filter* function. Please note negative signs are added to all 'a' coefficients for the direct form I filter.

from scipy import signal

def gen_butterworth(corner_frequency):

"""

Generate coefficients for a second order butterworth low-pass filter.

Corner frequencies for laser lock box second harmonic filtering should be in the range: 1 kHz < corner frequency < 31.25 MHz.

"""

sample_rate = 31.25e6

normalised_corner = corner_frequency / (sample_rate / 2)

b, a = signal.butter(2, normalised_corner, 'low', analog = False)

coefficient_array = [[1.0, b[0], b[1], b[2], -a[1], -a[2]],

[1.0, 1.0, 0.0, 0.0, 0.0, 0.0]]

return coefficient_array