def get_waveform_filter(out, template=None, **kwargs): """Return a frequency domain waveform filter for the specified approximant """ n = len(out) input_params = props(template, **kwargs) if input_params['approximant'] in filter_approximants(_scheme.mgr.state): wav_gen = filter_wav[type(_scheme.mgr.state)] htilde = wav_gen[input_params['approximant']](out=out, **input_params) htilde.resize(n) htilde.chirp_length = get_waveform_filter_length_in_time( **input_params) htilde.length_in_time = htilde.chirp_length return htilde if input_params['approximant'] in fd_approximants(_scheme.mgr.state): wav_gen = fd_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) hp.resize(n) out[0:len(hp)] = hp[:] hp = FrequencySeries(out, delta_f=hp.delta_f, copy=False) hp.chirp_length = get_waveform_filter_length_in_time(**input_params) hp.length_in_time = hp.chirp_length return hp elif input_params['approximant'] in td_approximants(_scheme.mgr.state): # N: number of time samples required N = (n - 1) * 2 delta_f = 1.0 / (N * input_params['delta_t']) wav_gen = td_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) # taper the time series hp if required if ('taper' in input_params.keys() and \ input_params['taper'] is not None): hp = wfutils.taper_timeseries(hp, input_params['taper'], return_lal=False) # total duration of the waveform tmplt_length = len(hp) * hp.delta_t # for IMR templates the zero of time is at max amplitude (merger) # thus the start time is minus the duration of the template from # lower frequency cutoff to merger, i.e. minus the 'chirp time' tChirp = -float(hp.start_time) # conversion from LIGOTimeGPS hp.resize(N) k_zero = int(hp.start_time / hp.delta_t) hp.roll(k_zero) htilde = FrequencySeries(out, delta_f=delta_f, copy=False) fft(hp.astype(real_same_precision_as(htilde)), htilde) htilde.length_in_time = tmplt_length htilde.chirp_length = tChirp return htilde else: raise ValueError("Approximant %s not available" % (input_params['approximant']))
def get_waveform_filter(out, template=None, **kwargs): """Return a frequency domain waveform filter for the specified approximant """ n = len(out) input_params = props(template, **kwargs) if input_params['approximant'] in filter_approximants(_scheme.mgr.state): wav_gen = filter_wav[type(_scheme.mgr.state)] htilde = wav_gen[input_params['approximant']](out=out, **input_params) htilde.resize(n) htilde.chirp_length = get_waveform_filter_length_in_time(**input_params) htilde.length_in_time = htilde.chirp_length return htilde if input_params['approximant'] in fd_approximants(_scheme.mgr.state): wav_gen = fd_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) hp.resize(n) out[0:len(hp)] = hp[:] hp = FrequencySeries(out, delta_f=hp.delta_f, copy=False) hp.chirp_length = get_waveform_filter_length_in_time(**input_params) hp.length_in_time = hp.chirp_length return hp elif input_params['approximant'] in td_approximants(_scheme.mgr.state): # N: number of time samples required N = (n-1)*2 delta_f = 1.0 / (N * input_params['delta_t']) wav_gen = td_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) # taper the time series hp if required if ('taper' in input_params.keys() and \ input_params['taper'] is not None): hp = wfutils.taper_timeseries(hp, input_params['taper'], return_lal=False) # total duration of the waveform tmplt_length = len(hp) * hp.delta_t # for IMR templates the zero of time is at max amplitude (merger) # thus the start time is minus the duration of the template from # lower frequency cutoff to merger, i.e. minus the 'chirp time' tChirp = - float( hp.start_time ) # conversion from LIGOTimeGPS hp.resize(N) k_zero = int(hp.start_time / hp.delta_t) hp.roll(k_zero) htilde = FrequencySeries(out, delta_f=delta_f, copy=False) fft(hp.astype(real_same_precision_as(htilde)), htilde) htilde.length_in_time = tmplt_length htilde.chirp_length = tChirp return htilde else: raise ValueError("Approximant %s not available" % (input_params['approximant']))
def td_waveform_to_fd_waveform(waveform, out=None, length=None, buffer_length=100): """ Convert a time domain into a frequency domain waveform by FFT. As a waveform is assumed to "wrap" in the time domain one must be careful to ensure the waveform goes to 0 at both "boundaries". To ensure this is done correctly the waveform must have the epoch set such the merger time is at t=0 and the length of the waveform should be shorter than the desired length of the FrequencySeries (times 2 - 1) so that zeroes can be suitably pre- and post-pended before FFTing. If given, out is a memory array to be used as the output of the FFT. If not given memory is allocated internally. If present the length of the returned FrequencySeries is determined from the length out. If out is not given the length can be provided expicitly, or it will be chosen as the nearest power of 2. If choosing length explicitly the waveform length + buffer_length is used when choosing the nearest binary number so that some zero padding is always added. """ # Figure out lengths and set out if needed if out is None: if length is None: N = pnutils.nearest_larger_binary_number(len(waveform) + \ buffer_length) n = int(N // 2) + 1 else: n = length N = (n - 1) * 2 out = zeros(n, dtype=complex_same_precision_as(waveform)) else: n = len(out) N = (n - 1) * 2 delta_f = 1. / (N * waveform.delta_t) # total duration of the waveform tmplt_length = len(waveform) * waveform.delta_t if len(waveform) > N: err_msg = "The time domain template is longer than the intended " err_msg += "duration in the frequency domain. This situation is " err_msg += "not supported in this function. Please shorten the " err_msg += "waveform appropriately before calling this function or " err_msg += "increase the allowed waveform length. " err_msg += "Waveform length (in samples): {}".format(len(waveform)) err_msg += ". Intended length: {}.".format(N) raise ValueError(err_msg) # for IMR templates the zero of time is at max amplitude (merger) # thus the start time is minus the duration of the template from # lower frequency cutoff to merger, i.e. minus the 'chirp time' tChirp = -float(waveform.start_time) # conversion from LIGOTimeGPS waveform.resize(N) k_zero = int(waveform.start_time / waveform.delta_t) waveform.roll(k_zero) htilde = FrequencySeries(out, delta_f=delta_f, copy=False) fft(waveform.astype(real_same_precision_as(htilde)), htilde) htilde.length_in_time = tmplt_length htilde.chirp_length = tChirp return htilde
def td_waveform_to_fd_waveform(waveform, out=None, length=None, buffer_length=100): """ Convert a time domain into a frequency domain waveform by FFT. As a waveform is assumed to "wrap" in the time domain one must be careful to ensure the waveform goes to 0 at both "boundaries". To ensure this is done correctly the waveform must have the epoch set such the merger time is at t=0 and the length of the waveform should be shorter than the desired length of the FrequencySeries (times 2 - 1) so that zeroes can be suitably pre- and post-pended before FFTing. If given, out is a memory array to be used as the output of the FFT. If not given memory is allocated internally. If present the length of the returned FrequencySeries is determined from the length out. If out is not given the length can be provided expicitly, or it will be chosen as the nearest power of 2. If choosing length explicitly the waveform length + buffer_length is used when choosing the nearest binary number so that some zero padding is always added. """ # Figure out lengths and set out if needed if out is None: if length is None: N = pnutils.nearest_larger_binary_number(len(waveform) + \ buffer_length) n = int(N//2) + 1 else: n = length N = (n-1)*2 out = zeros(n, dtype=complex_same_precision_as(waveform)) else: n = len(out) N = (n-1)*2 delta_f = 1. / (N * waveform.delta_t) # total duration of the waveform tmplt_length = len(waveform) * waveform.delta_t if len(waveform) > N: err_msg = "The time domain template is longer than the intended " err_msg += "duration in the frequency domain. This situation is " err_msg += "not supported in this function. Please shorten the " err_msg += "waveform appropriately before calling this function or " err_msg += "increase the allowed waveform length. " err_msg += "Waveform length (in samples): {}".format(len(waveform)) err_msg += ". Intended length: {}.".format(N) raise ValueError(err_msg) # for IMR templates the zero of time is at max amplitude (merger) # thus the start time is minus the duration of the template from # lower frequency cutoff to merger, i.e. minus the 'chirp time' tChirp = - float( waveform.start_time ) # conversion from LIGOTimeGPS waveform.resize(N) k_zero = int(waveform.start_time / waveform.delta_t) waveform.roll(k_zero) htilde = FrequencySeries(out, delta_f=delta_f, copy=False) fft(waveform.astype(real_same_precision_as(htilde)), htilde) htilde.length_in_time = tmplt_length htilde.chirp_length = tChirp return htilde
def get_waveform_filter(out, template=None, **kwargs): """Return a frequency domain waveform filter for the specified approximant """ n = len(out) input_params = props(template, **kwargs) if input_params['approximant'] in filter_approximants(_scheme.mgr.state): wav_gen = filter_wav[type(_scheme.mgr.state)] htilde = wav_gen[input_params['approximant']](out=out, **input_params) htilde.resize(n) htilde.chirp_length = get_waveform_filter_length_in_time( **input_params) htilde.length_in_time = htilde.chirp_length return htilde if input_params['approximant'] in fd_approximants(_scheme.mgr.state): wav_gen = fd_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) hp.resize(n) out[0:len(hp)] = hp[:] hp = FrequencySeries(out, delta_f=hp.delta_f, copy=False) hp.chirp_length = get_waveform_filter_length_in_time(**input_params) hp.length_in_time = hp.chirp_length return hp elif input_params['approximant'] in td_approximants(_scheme.mgr.state): # N: number of time samples required N = (n - 1) * 2 delta_f = 1.0 / (N * input_params['delta_t']) wav_gen = td_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) # taper the time series hp if required if ('taper' in input_params.keys() and \ input_params['taper'] is not None): hp = wfutils.taper_timeseries(hp, input_params['taper'], return_lal=False) return td_waveform_to_fd_waveform(hp, out=out) else: raise ValueError("Approximant %s not available" % (input_params['approximant']))
def get_waveform_filter(out, template=None, **kwargs): """Return a frequency domain waveform filter for the specified approximant """ n = len(out) input_params = props(template, **kwargs) if input_params['approximant'] in filter_approximants(_scheme.mgr.state): wav_gen = filter_wav[type(_scheme.mgr.state)] htilde = wav_gen[input_params['approximant']](out=out, **input_params) htilde.resize(n) htilde.chirp_length = get_waveform_filter_length_in_time(**input_params) htilde.length_in_time = htilde.chirp_length return htilde if input_params['approximant'] in fd_approximants(_scheme.mgr.state): wav_gen = fd_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) hp.resize(n) out[0:len(hp)] = hp[:] hp = FrequencySeries(out, delta_f=hp.delta_f, copy=False) hp.chirp_length = get_waveform_filter_length_in_time(**input_params) hp.length_in_time = hp.chirp_length return hp elif input_params['approximant'] in td_approximants(_scheme.mgr.state): # N: number of time samples required N = (n-1)*2 delta_f = 1.0 / (N * input_params['delta_t']) wav_gen = td_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) # taper the time series hp if required if ('taper' in input_params.keys() and \ input_params['taper'] is not None): hp = wfutils.taper_timeseries(hp, input_params['taper'], return_lal=False) return td_waveform_to_fd_waveform(hp, out=out) else: raise ValueError("Approximant %s not available" % (input_params['approximant']))
def get_two_pol_waveform_filter(outplus, outcross, template, **kwargs): """Return a frequency domain waveform filter for the specified approximant. Unlike get_waveform_filter this function returns both h_plus and h_cross components of the waveform, which are needed for searches where h_plus and h_cross are not related by a simple phase shift. """ n = len(outplus) # If we don't have an inclination column alpha3 might be used if not hasattr(template, 'inclination') and 'inclination' not in kwargs: if hasattr(template, 'alpha3'): kwargs['inclination'] = template.alpha3 input_params = props(template, **kwargs) if input_params['approximant'] in fd_approximants(_scheme.mgr.state): wav_gen = fd_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) hp.resize(n) hc.resize(n) outplus[0:len(hp)] = hp[:] hp = FrequencySeries(outplus, delta_f=hp.delta_f, copy=False) outcross[0:len(hc)] = hc[:] hc = FrequencySeries(outcross, delta_f=hc.delta_f, copy=False) hp.chirp_length = get_waveform_filter_length_in_time(**input_params) hp.length_in_time = hp.chirp_length hc.chirp_length = hp.chirp_length hc.length_in_time = hp.length_in_time return hp, hc elif input_params['approximant'] in td_approximants(_scheme.mgr.state): # N: number of time samples required N = (n-1)*2 delta_f = 1.0 / (N * input_params['delta_t']) wav_gen = td_wav[type(_scheme.mgr.state)] hp, hc = wav_gen[input_params['approximant']](**input_params) # taper the time series hp if required if 'taper' in input_params.keys() and \ input_params['taper'] is not None: hp = wfutils.taper_timeseries(hp, input_params['taper'], return_lal=False) hc = wfutils.taper_timeseries(hc, input_params['taper'], return_lal=False) # total duration of the waveform tmplt_length = len(hp) * hp.delta_t # for IMR templates the zero of time is at max amplitude (merger) # thus the start time is minus the duration of the template from # lower frequency cutoff to merger, i.e. minus the 'chirp time' tChirp = - float( hp.start_time ) # conversion from LIGOTimeGPS hp.resize(N) hc.resize(N) k_zero = int(hp.start_time / hp.delta_t) hp.roll(k_zero) hc.roll(k_zero) hp_tilde = FrequencySeries(outplus, delta_f=delta_f, copy=False) hc_tilde = FrequencySeries(outcross, delta_f=delta_f, copy=False) fft(hp.astype(real_same_precision_as(hp_tilde)), hp_tilde) fft(hc.astype(real_same_precision_as(hc_tilde)), hc_tilde) hp_tilde.length_in_time = tmplt_length hp_tilde.chirp_length = tChirp hc_tilde.length_in_time = tmplt_length hc_tilde.chirp_length = tChirp return hp_tilde, hc_tilde else: raise ValueError("Approximant %s not available" % (input_params['approximant']))