Source code for pycbc.waveform.multiband

""" Tools and functions to calculate interpolate waveforms using multi-banding
"""
import numpy

from pycbc.types import TimeSeries, zeros


[docs]def multiband_fd_waveform(bands=None, lengths=None, overlap=0, **p): """ Generate a fourier domain waveform using multibanding Speed up generation of a fouerier domain waveform using multibanding. This allows for multi-rate sampling of the frequeny space. Each band is smoothed and stitched together to produce the final waveform. The base approximant must support 'f_ref' and 'f_final'. The other parameters must be chosen carefully by the user. Parameters ---------- bands: list or str The frequencies to split the waveform by. These should be chosen so that the corresponding length include all the waveform's frequencies within this band. lengths: list or str The corresponding length for each frequency band. This sets the resolution of the subband and should be chosen carefully so that it is sufficiently long to include all of the bands frequency content. overlap: float The frequency width to apply tapering between bands. params: dict The remaining keyworkd arguments passed to the base approximant waveform generation. Returns ------- hp: pycbc.types.FrequencySeries Plus polarization hc: pycbc.type.FrequencySeries Cross polarization """ from pycbc.waveform import get_fd_waveform if isinstance(bands, str): bands = [float(s) for s in bands.split(' ')] if isinstance(lengths, str): lengths = [float(s) for s in lengths.split(' ')] p['approximant'] = p['base_approximant'] df = p['delta_f'] fmax = p['f_final'] flow = p['f_lower'] bands = [flow] + bands + [fmax] dfs = [df] + [1.0 / l for l in lengths] dt = 1.0 / (2.0 * fmax) tlen = int(1.0 / dt / df) flen = tlen / 2 + 1 wf_plus = TimeSeries(zeros(tlen, dtype=numpy.float32), copy=False, delta_t=dt, epoch=-1.0/df) wf_cross = TimeSeries(zeros(tlen, dtype=numpy.float32), copy=False, delta_t=dt, epoch=-1.0/df) # Iterate over the sub-bands for i in range(len(lengths)+1): taper_start = taper_end = False if i != 0: taper_start = True if i != len(lengths): taper_end = True # Generate waveform for sub-band of full waveform start = bands[i] stop = bands[i+1] p2 = p.copy() p2['delta_f'] = dfs[i] p2['f_lower'] = start p2['f_final'] = stop if taper_start: p2['f_lower'] -= overlap / 2.0 if taper_end: p2['f_final'] += overlap / 2.0 tlen = int(1.0 / dt / dfs[i]) flen = tlen / 2 + 1 hp, hc = get_fd_waveform(**p2) # apply window function to smooth over transition regions kmin = int(p2['f_lower'] / dfs[i]) kmax = int(p2['f_final'] / dfs[i]) taper = numpy.hanning(int(overlap * 2 / dfs[i])) for wf, h in zip([wf_plus, wf_cross], [hp, hc]): h = h.astype(numpy.complex64) if taper_start: h[kmin:kmin + len(taper) // 2] *= taper[:len(taper)//2] if taper_end: l, r = kmax - (len(taper) - len(taper) // 2), kmax h[l:r] *= taper[len(taper)//2:] # add frequency band to total and use fft to interpolate h.resize(flen) h = h.to_timeseries() wf[len(wf)-len(h):] += h return (wf_plus.to_frequencyseries().astype(hp.dtype), wf_cross.to_frequencyseries().astype(hp.dtype))