Skip to content

Commit

Permalink
feat(delay): add option to low-pass with null delay filter
Browse files Browse the repository at this point in the history
  • Loading branch information
ljgray committed May 13, 2024
1 parent 92db128 commit 8346e3c
Showing 1 changed file with 30 additions and 6 deletions.
36 changes: 30 additions & 6 deletions draco/analysis/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -1861,15 +1861,24 @@ def delay_spectrum_wiener_filter(
return y_spec


def null_delay_filter(freq, max_delay, mask, num_delay=200, tol=1e-8, window=True):
def null_delay_filter(
freq,
delay_cut,
mask,
num_delay=200,
tol=1e-8,
window=True,
type_="high",
lapack_driver="gesvd",
):
"""Take frequency data and null out any delays below some value.
Parameters
----------
freq : np.ndarray[freq]
Frequencies we have data at.
max_delay : float
Maximum delay to keep.
delay_cut : float
Delay cut to apply.
mask : np.ndarray[freq]
Frequencies to mask out.
num_delay : int, optional
Expand All @@ -1878,17 +1887,27 @@ def null_delay_filter(freq, max_delay, mask, num_delay=200, tol=1e-8, window=Tru
Cut off value for singular values.
window : bool, optional
Apply a window function to the data while filtering.
type_ : str, optional
Whether to apply a high-pass or low-pass filter. Options are
`high` or `low`. Default is `high`.
lapack_driver : str, optional
Which lapack driver to use in the SVD. Options are 'gesvd' or 'gesdd'.
'gesdd' is generally faster, but seems to experience convergence issues.
Default is 'gesvd'.
Returns
-------
filter : np.ndarray[freq, freq]
The filter as a 2D matrix.
"""
if type_ not in {"high", "low"}:
raise ValueError(f"Filter type must be one of [high, low]. Got {type_}")

# Construct the window function
x = (freq - freq.min()) / freq.ptp()
w = tools.window_generalised(x, window="nuttall")

delay = np.linspace(-max_delay, max_delay, num_delay)
delay = np.linspace(-delay_cut, delay_cut, num_delay)

# Construct the Fourier matrix
F = mask[:, np.newaxis] * np.exp(
Expand All @@ -1904,9 +1923,14 @@ def null_delay_filter(freq, max_delay, mask, num_delay=200, tol=1e-8, window=Tru
# to be the fault of MKL (see https://github.com/scipy/scipy/issues/10032 and links
# therein). This seems to be limited to the `gesdd` LAPACK routine, so we can get
# around it by switching to `gesvd`.
u, sig, vh = la.svd(F, lapack_driver="gesvd")
u, sig, vh = la.svd(F, full_matrices=False, lapack_driver=lapack_driver)
nmodes = np.sum(sig > tol * sig.max())
p = u[:, :nmodes]

# Select the modes to null out based on the filter type
if type_ == "high":
p = u[:, :nmodes]
elif type_ == "low":
p = u[:, nmodes:]

# Construct a projection matrix for the filter
proj = np.identity(len(freq)) - np.dot(p, p.T.conj())
Expand Down

0 comments on commit 8346e3c

Please sign in to comment.