Create method in darm.py for computing the relative delay between paths for Front-End Delta L External Construction
Since O1, we've been approximating the phase loss of super-Nyquist poles in A and C with delays in the "front-end" calibration, which combines the pre-GDS-pipeline versions of C and A to form "DELTAL_EXTERNAL," the "good enough for commissioning" product that's available in real-time in the control room.
We do this by accepting a ~200 [us] delay in DELTAL EXTERNAL via the following logic:
DL = (1/C) * darm_err + A * darm_ctrl
DL = (1/ [C_lf exp(2*pi*i*f*t_C_delay)]) * d_err + A_lf * exp(2*pi*i*f*t_A_delay) * D
DL = (1/C_lf) * d_err * exp( - 2*pi*i*f*t_C_delay) + A_lf * D * exp(2*pi*i*f*t_A_delay)
DL = exp( - 2*pi*i*f*t_C_delay) [ (1/C_lf)*d_err + A_lf * D exp(2*pi*i*f*(t_A_delay+t_C_delay)) ]
DL exp(2*pi*i*f*t_C_delay) = (1/C_lf)*d_err + A_lf * D exp(2*pi*i*f*(t_A_delay+t_C_delay))
See diagrammatic explanation of this in 22117.
We need to calculate what t_A_delay + t_C_delay is from the darm model, and install this in the front end. Of course, this "delay" is an approximation to a frequency response that is just that -- frequency dependent. So, we chose to compute this delay at "the frequency where it matters" -- the DARM loop unity gain frequency, where A and (1/C) better be crossing over with equal phase.
There are currently two technologies for installing this in the front-end:
- the "integer clock cycle delay" and,
- the "thiran filter"
The first method was implemented early because it's relatively easy to build a real-time buffer that holds a halve for n number of clock cycles before passing it on. So this is what we used for a while. Then around O2-ish, someone realized this delay is sometimes not very close to an integer value, so we barked up the "thiran filter approximation" tree, which creates an IIR filter that acts like a non-integer delay on a signal. L1 prototyped this and was successful and has continued to use it through O3. H1's delay happened to remain quite close to an integer value, so they stuck with using an integer clock cycle system.
Thus, pyDARM needs to compute both:
- Find the DARM loop UGF
- Compute the relative delay (i.e. the phase residual) between the actuation and sensing function, as a function of frequency.
- Spit out an integer clock cycle equivalent
From there, we can either write another method to install the clock cycle, or another method to compute the thiran filter and install it.
Open question: we've computed the thiran filter only ever in Matlab. Does python (maybe the signal package of scipy?) have a thiran filter calculator?
Here're the scripts that we've used in the past as examples to get started: