def colored_noise(psd, start_time, end_time, seed=0, sample_rate=16384, low_frequency_cutoff=1.0, filter_duration=128): """ Create noise from a PSD Return noise from the chosen PSD. Note that if unique noise is desired a unique seed should be provided. Parameters ---------- psd : pycbc.types.FrequencySeries PSD to color the noise start_time : int Start time in GPS seconds to generate noise end_time : int End time in GPS seconds to generate nosie seed : {None, int} The seed to generate the noise. sample_rate: {16384, float} The sample rate of the output data. Keep constant if you want to ensure continuity between disjoint time spans. low_frequency_cutof : {1.0, float} The low frequency cutoff to pass to the PSD generation. filter_duration : {128, float} The duration in seconds of the coloring filter Returns -------- noise : TimeSeries A TimeSeries containing gaussian noise colored by the given psd. """ psd = psd.copy() flen = int(sample_rate / psd.delta_f) // 2 + 1 oldlen = len(psd) psd.resize(flen) # Want to avoid zeroes in PSD. max_val = psd.max() for i in range(len(psd)): if i >= (oldlen - 1): psd.data[i] = psd[oldlen - 2] if psd[i] == 0: psd.data[i] = max_val fil_len = int(filter_duration * sample_rate) wn_dur = int(end_time - start_time) + 2 * filter_duration if psd.delta_f >= 1. / (2. * filter_duration): # If the PSD is short enough, this method is less memory intensive than # resizing and then calling inverse_spectrum_truncation psd = pycbc.psd.interpolate(psd, 1.0 / (2. * filter_duration)) # inverse_spectrum_truncation truncates the inverted PSD. To truncate # the non-inverted PSD we give it the inverted PSD to truncate and then # invert the output. psd = 1. / pycbc.psd.inverse_spectrum_truncation( 1. / psd, fil_len, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') psd = psd.astype(complex_same_precision_as(psd)) # Zero-pad the time-domain PSD to desired length. Zeroes must be added # in the middle, so some rolling between a resize is used. psd = psd.to_timeseries() psd.roll(fil_len) psd.resize(int(wn_dur * sample_rate)) psd.roll(-fil_len) # As time series is still mirrored the complex frequency components are # 0. But convert to real by using abs as in inverse_spectrum_truncate psd = psd.to_frequencyseries() else: psd = pycbc.psd.interpolate(psd, 1.0 / wn_dur) psd = 1. / pycbc.psd.inverse_spectrum_truncation( 1. / psd, fil_len, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') kmin = int(low_frequency_cutoff / psd.delta_f) psd[:kmin].clear() asd = (psd.squared_norm())**0.25 del psd white_noise = normal(start_time - filter_duration, end_time + filter_duration, seed=seed, sample_rate=sample_rate) white_noise = white_noise.to_frequencyseries() # Here we color. Do not want to duplicate memory here though so use '*=' white_noise *= asd del asd colored = white_noise.to_timeseries(delta_t=1.0 / sample_rate) del white_noise return colored.time_slice(start_time, end_time)
def colored_noise(psd, start_time, end_time, seed=0, low_frequency_cutoff=1.0): """ Create noise from a PSD Return noise from the chosen PSD. Note that if unique noise is desired a unique seed should be provided. Parameters ---------- psd : pycbc.types.FrequencySeries PSD to color the noise start_time : int Start time in GPS seconds to generate noise end_time : int End time in GPS seconds to generate nosie seed : {None, int} The seed to generate the noise. low_frequency_cutof : {1.0, float} The low frequency cutoff to pass to the PSD generation. Returns -------- noise : TimeSeries A TimeSeries containing gaussian noise colored by the given psd. """ psd = psd.copy() flen = int(SAMPLE_RATE / psd.delta_f) / 2 + 1 oldlen = len(psd) psd.resize(flen) # Want to avoid zeroes in PSD. max_val = psd.max() for i in xrange(len(psd)): if i >= (oldlen-1): psd.data[i] = psd[oldlen - 2] if psd[i] == 0: psd.data[i] = max_val wn_dur = int(end_time - start_time) + 2*FILTER_LENGTH if psd.delta_f >= 1. / (2.*FILTER_LENGTH): # If the PSD is short enough, this method is less memory intensive than # resizing and then calling inverse_spectrum_truncation psd = pycbc.psd.interpolate(psd, 1.0 / (2.*FILTER_LENGTH)) # inverse_spectrum_truncation truncates the inverted PSD. To truncate # the non-inverted PSD we give it the inverted PSD to truncate and then # invert the output. psd = 1. / pycbc.psd.inverse_spectrum_truncation(1./psd, FILTER_LENGTH * SAMPLE_RATE, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') psd = psd.astype(complex_same_precision_as(psd)) # Zero-pad the time-domain PSD to desired length. Zeroes must be added # in the middle, so some rolling between a resize is used. psd = psd.to_timeseries() psd.roll(SAMPLE_RATE * FILTER_LENGTH) psd.resize(wn_dur * SAMPLE_RATE) psd.roll(-SAMPLE_RATE * FILTER_LENGTH) # As time series is still mirrored the complex frequency components are # 0. But convert to real by using abs as in inverse_spectrum_truncate psd = psd.to_frequencyseries() else: psd = pycbc.psd.interpolate(psd, 1.0 / wn_dur) psd = 1. / pycbc.psd.inverse_spectrum_truncation(1./psd, FILTER_LENGTH * SAMPLE_RATE, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') kmin = int(low_frequency_cutoff / psd.delta_f) psd[:kmin].clear() asd = (psd.real())**0.5 del psd white_noise = normal(start_time - FILTER_LENGTH, end_time + FILTER_LENGTH, seed=seed) white_noise = white_noise.to_frequencyseries() # Here we color. Do not want to duplicate memory here though so use '*=' white_noise *= asd del asd colored = white_noise.to_timeseries() del white_noise return colored.time_slice(start_time, end_time)
def colored_noise(psd, start_time, end_time, seed=0, low_frequency_cutoff=1.0): """ Create noise from a PSD Return noise from the chosen PSD. Note that if unique noise is desired a unique seed should be provided. Parameters ---------- psd : pycbc.types.FrequencySeries PSD to color the noise start_time : int Start time in GPS seconds to generate noise end_time : int End time in GPS seconds to generate nosie seed : {None, int} The seed to generate the noise. low_frequency_cutof : {1.0, float} The low frequency cutoff to pass to the PSD generation. Returns -------- noise : TimeSeries A TimeSeries containing gaussian noise colored by the given psd. """ psd = psd.copy() flen = int(SAMPLE_RATE / psd.delta_f) / 2 + 1 oldlen = len(psd) psd.resize(flen) # Want to avoid zeroes in PSD. max_val = psd.max() for i in xrange(len(psd)): if i >= (oldlen - 1): psd.data[i] = psd[oldlen - 2] if psd[i] == 0: psd.data[i] = max_val wn_dur = int(end_time - start_time) + 2 * FILTER_LENGTH if psd.delta_f >= 1. / (2. * FILTER_LENGTH): # If the PSD is short enough, this method is less memory intensive than # resizing and then calling inverse_spectrum_truncation psd = pycbc.psd.interpolate(psd, 1.0 / (2. * FILTER_LENGTH)) # inverse_spectrum_truncation truncates the inverted PSD. To truncate # the non-inverted PSD we give it the inverted PSD to truncate and then # invert the output. psd = 1. / pycbc.psd.inverse_spectrum_truncation( 1. / psd, FILTER_LENGTH * SAMPLE_RATE, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') psd = psd.astype(complex_same_precision_as(psd)) # Zero-pad the time-domain PSD to desired length. Zeroes must be added # in the middle, so some rolling between a resize is used. psd = psd.to_timeseries() psd.roll(SAMPLE_RATE * FILTER_LENGTH) psd.resize(wn_dur * SAMPLE_RATE) psd.roll(-SAMPLE_RATE * FILTER_LENGTH) # As time series is still mirrored the complex frequency components are # 0. But convert to real by using abs as in inverse_spectrum_truncate psd = psd.to_frequencyseries() else: psd = pycbc.psd.interpolate(psd, 1.0 / wn_dur) psd = 1. / pycbc.psd.inverse_spectrum_truncation( 1. / psd, FILTER_LENGTH * SAMPLE_RATE, low_frequency_cutoff=low_frequency_cutoff, trunc_method='hann') kmin = int(low_frequency_cutoff / psd.delta_f) psd[:kmin].clear() asd = (psd.real())**0.5 del psd white_noise = normal(start_time - FILTER_LENGTH, end_time + FILTER_LENGTH, seed=seed) white_noise = white_noise.to_frequencyseries() # Here we color. Do not want to duplicate memory here though so use '*=' white_noise *= asd del asd colored = white_noise.to_timeseries() del white_noise return colored.time_slice(start_time, end_time)