Matched filtering techniques for gravitational wave detection. Use when searching for signals in detector data using template waveforms, including both time-domain and frequency-domain approaches. Works with PyCBC for generating templates and performing matched filtering.
Matched filtering is the primary technique for detecting gravitational wave signals in noisy detector data. It correlates known template waveforms with the detector data to find signals with high signal-to-noise ratio (SNR).
Matched filtering requires:
PyCBC supports both time-domain and frequency-domain approaches.
Generate templates in time domain using get_td_waveform:
from pycbc.waveform import get_td_waveform
from pycbc.filter import matched_filter
# Generate time-domain waveform
hp, hc = get_td_waveform(
approximant='IMRPhenomD', # or 'SEOBNRv4_opt', 'TaylorT4'
mass1=25, # Primary mass (solar masses)
mass2=20, # Secondary mass (solar masses)
delta_t=conditioned.delta_t, # Must match data sampling
f_lower=20 # Lower frequency cutoff (Hz)
)
# Resize template to match data length
hp.resize(len(conditioned))
# Align template: cyclic shift so merger is at the start
template = hp.cyclic_time_shift(hp.start_time)
# Perform matched filtering
snr = matched_filter(
template,
conditioned,
psd=psd,
low_frequency_cutoff=20
)
# Crop edges corrupted by filtering
# Remove 4 seconds for PSD + 4 seconds for template length at start
# Remove 4 seconds at end for PSD
snr = snr.crop(4 + 4, 4)
# Find peak SNR
import numpy as np
peak_idx = np.argmax(abs(snr).numpy())
peak_snr = abs(snr[peak_idx])
Waveforms from get_td_waveform have the merger at time zero. For matched filtering, we typically want the merger aligned at the start of the template. cyclic_time_shift rotates the waveform appropriately.
Generate templates in frequency domain using get_fd_waveform:
from pycbc.waveform import get_fd_waveform
from pycbc.filter import matched_filter
# Calculate frequency resolution
delta_f = 1.0 / conditioned.duration
# Generate frequency-domain waveform
hp, hc = get_fd_waveform(
approximant='IMRPhenomD',
mass1=25,
mass2=20,
delta_f=delta_f, # Frequency resolution (must match data)
f_lower=20 # Lower frequency cutoff (Hz)
)
# Resize template to match PSD length
hp.resize(len(psd))
# Perform matched filtering
snr = matched_filter(
hp,
conditioned,
psd=psd,
low_frequency_cutoff=20
)
# Find peak SNR
import numpy as np
peak_idx = np.argmax(abs(snr).numpy())
peak_snr = abs(snr[peak_idx])
get_td_waveform)get_fd_waveform)Common waveform approximants:
# Phenomenological models (fast, good accuracy)
'IMRPhenomD' # Good for most binary black hole systems
'IMRPhenomPv2' # More accurate for precessing systems
# Effective One-Body models (very accurate, slower)
'SEOBNRv4_opt' # Optimized EOB model (time-domain only typically)
# Post-Newtonian models (approximate, fast)
'TaylorT4' # Post-Newtonian expansion
Note: Some approximants may not be available in frequency domain. If get_fd_waveform fails, use get_td_waveform instead.
low_frequency_cutoffhp.resize(len(conditioned)) - match data lengthhp.resize(len(psd)) - match PSD lengthAfter matched filtering, crop edges corrupted by:
snr.crop(8, 4) for time-domain, snr.crop(4, 4) for frequency-domaindelta_t/delta_f must match dataabs() for SNR: Matched filter returns complex SNR; use magnitudeProblem: "Approximant not available" error
Problem: Template size mismatch
Problem: Poor SNR even with correct masses
Problem: Edge artifacts in SNR time series
pip install pycbc numpy