def bandlimited_interpolate(series, delta_f): """Return a new PSD that has been interpolated to the desired delta_f. Parameters ---------- series : FrequencySeries Frequency series to be interpolated. delta_f : float The desired delta_f of the output Returns ------- interpolated series : FrequencySeries A new FrequencySeries that has been interpolated. """ series = FrequencySeries(series, dtype=complex_same_precision_as(series), delta_f=series.delta_f) N = (len(series) - 1) * 2 delta_t = 1.0 / series.delta_f / N new_N = int(1.0 / (delta_t * delta_f)) new_n = new_N / 2 + 1 series_in_time = TimeSeries(zeros(N), dtype=real_same_precision_as(series), delta_t=delta_t) ifft(series, series_in_time) padded_series_in_time = TimeSeries(zeros(new_N), dtype=series_in_time.dtype, delta_t=delta_t) padded_series_in_time[0:N / 2] = series_in_time[0:N / 2] padded_series_in_time[new_N - N / 2:new_N] = series_in_time[N / 2:N] interpolated_series = FrequencySeries(zeros(new_n), dtype=series.dtype, delta_f=delta_f) fft(padded_series_in_time, interpolated_series) return interpolated_series
def _lalsim_td_waveform(**p): fail_tolerant_waveform_generation lal_pars = _check_lal_pars(p) #nonGRparams can be straightforwardly added if needed, however they have to # be invoked one by one try: hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform( float(pnutils.solar_mass_to_kg(p['mass1'])), float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']), float(p['spin1y']), float(p['spin1z']), float(p['spin2x']), float(p['spin2y']), float(p['spin2z']), pnutils.megaparsecs_to_meters(float(p['distance'])), float(p['inclination']), float(p['coa_phase']), float(p['long_asc_nodes']), float(p['eccentricity']), float(p['mean_per_ano']), float(p['delta_t']), float(p['f_lower']), float(p['f_ref']), lal_pars, _lalsim_enum[p['approximant']]) except RuntimeError: if not fail_tolerant_waveform_generation: raise # For some cases failure modes can occur. Here we add waveform-specific # instructions to try to work with waveforms that are known to fail. if 'SEOBNRv3' in p['approximant']: # Try doubling the sample time and redoing. # Don't want to get stuck in a loop though! if 'delta_t_orig' not in p: p['delta_t_orig'] = p['delta_t'] p['delta_t'] = p['delta_t'] / 2. if p['delta_t_orig'] / p['delta_t'] > 9: raise hp, hc = _lalsim_td_waveform(**p) p['delta_t'] = p['delta_t_orig'] hp = resample_to_delta_t(hp, hp.delta_t * 2) hc = resample_to_delta_t(hc, hc.delta_t * 2) return hp, hc raise #lal.DestroyDict(lal_pars) hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch) hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch) return hp, hc
def _lalsim_td_waveform(**p): lal_pars = _check_lal_pars(p) #nonGRparams can be straightforwardly added if needed, however they have to # be invoked one by one hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform( float(pnutils.solar_mass_to_kg(p['mass1'])), float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']), float(p['spin1y']), float(p['spin1z']), float(p['spin2x']), float(p['spin2y']), float(p['spin2z']), pnutils.megaparsecs_to_meters(float(p['distance'])), float(p['inclination']), float(p['coa_phase']), float(p['long_asc_nodes']), float(p['eccentricity']), float(p['mean_per_ano']), float(p['delta_t']), float(p['f_lower']), float(p['f_ref']), lal_pars, _lalsim_enum[p['approximant']]) #lal.DestroyDict(lal_pars) hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch) hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch) return hp, hc
def _lalsim_td_waveform(**p): flags = lalsimulation.SimInspiralCreateWaveformFlags() lalsimulation.SimInspiralSetSpinOrder(flags, p['spin_order']) lalsimulation.SimInspiralSetTidalOrder(flags, p['tidal_order']) hp, hc = lalsimulation.SimInspiralChooseTDWaveform( float(p['coa_phase']), float(p['delta_t']), float(pnutils.solar_mass_to_kg(p['mass1'])), float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']), float(p['spin1y']), float(p['spin1z']), float(p['spin2x']), float(p['spin2y']), float(p['spin2z']), float(p['f_lower']), float(p['f_ref']), pnutils.megaparsecs_to_meters(float(p['distance'])), float(p['inclination']), float(p['lambda1']), float(p['lambda2']), flags, None, int(p['amplitude_order']), int(p['phase_order']), _lalsim_enum[p['approximant']]) hp = TimeSeries(hp.data.data[:] * 1, delta_t=hp.deltaT, epoch=hp.epoch) hc = TimeSeries(hc.data.data[:] * 1, delta_t=hc.deltaT, epoch=hc.epoch) return hp, hc
def __init__(self, ts, time_step=0.25, batch_size=32, dt=None): #from generate_split_data import whiten_data, resample_data self.batch_size = batch_size if not isinstance(ts, list): ts = [ts] self.ts = [] self.dt = [] for t in ts: if isinstance(t, TimeSeries): self.dt.append(t.delta_t) self.ts.append(t) elif isinstance(t, type(np.array([]))): if dt == None: msg = 'If the provided data is not a pycbc.types.TimeSeries' msg += 'a value dt must be provided.' raise ValueError(msg) else: self.dt.append(dt) self.ts.append(TimeSeries(t, delta_t=dt)) else: msg = 'The provided data needs to be either a list or a ' msg += 'single instance of either a pycbc.types.TimeSeries' msg += 'or a numpy.array.' raise ValueError(msg) for delta_t in self.dt: if not delta_t == self.dt[0]: raise ValueError('All data must have the same delta_t.') self.final_data_samples = 2048 #The delta_t for all data self.dt = self.dt[0] #How big is the window that is shifted over the data #(64s + 4s for cropping when whitening) self.window_size_time = 96.0 self.window_size = int(self.window_size_time / self.dt) #How many points are shifted each step self.stride = int(time_step / self.dt) #How many window shifts happen self.window_shifts = int( np.floor(float(len(self.ts[0]) - self.window_size) / self.stride)) self.resample_dt = [ 1.0 / 4096, 1.0 / 2048, 1.0 / 1024, 1.0 / 512, 1.0 / 256, 1.0 / 128, 1.0 / 64 ] self.resample_rates = [4096, 4096, 2048, 1024, 512, 256, 128, 64] self.num_samples = 2048 DF = 1.0 / 96 F_LEN = int(2.0 / (DF * self.dt)) self.psd = aLIGOZeroDetHighPower(length=F_LEN, delta_f=DF, low_freq_cutoff=20.0)
def generate_Whistle(f_lower,bw, duration, tc =0.5): ''' f_lower: lower frequency tc: fractional center time position (time at which fequency is min) bw: bandwidth in frequency domian''' t = np.linspace(0, duration, duration*4096) omega = f_lower + 2*pi*(bw/tc**2)*(t - tc*duration)**2 whistle = np.sin(omega*t) waveform = TimeSeries(whistle, delta_t=1/4096) return waveform
def cross_correlation(h1, l1, time, w=0.04): """This is the cross correlation function used by Creswell et al. We copied it directly from here: http://www.nbi.ku.dk/gravitational-waves/correlations.html (That notebook is linked from: http://www.nbi.ku.dk/gravitational-waves/gravitational-waves.html) The only changes we make here are to accomodate our data types: in that notebook the strain and times come from 2D numpy arrays that were loaded from text files. Here, ``h1`` and ``l1`` are pycbc.TimeSeries types. We note these differences below. """ # The time steps can be retrieved from the TimeSeries.sample_times # attribute, which is a pycbc.types.Array; the `.numpy()` converts that # to a numpy.array. h1_res_times = h1.sample_times.numpy() h1_res_strain = h1.numpy() l1_res_times = l1.sample_times.numpy() l1_res_strain = l1.numpy() fs = 1. / (h1_res_times[1] - h1_res_times[0]) min_indxt = numpy.where( abs(h1_res_times - time) == abs(h1_res_times - time).min())[0][0] max_indxt = numpy.where( abs(h1_res_times - (time + w)) == abs(h1_res_times - (time + w)).min())[0][0] deltatau = 0.01 tauind_min = int(-deltatau * fs) tauind_max = int(+deltatau * fs) tauind = numpy.arange(tauind_min, tauind_max) tau = tauind / fs corr = [] for i in tauind: corr.append( numpy.corrcoef( h1_res_strain[min_indxt + abs(tauind_min) + i:max_indxt - abs(tauind_max) + i], l1_res_strain[min_indxt + abs(tauind_min):max_indxt - abs(tauind_max)])[0][1]) corr = numpy.array(corr) return tau, TimeSeries(corr, epoch=tauind_min * h1.delta_t, delta_t=h1.delta_t)
def project_wave(self, hp, hc, longitude, latitude, polarization): """Return the strain of a wave with given amplitudes and angles as measured by the detector. """ h_lal = lalsimulation.SimDetectorStrainREAL8TimeSeries( hp.astype(np.float64).lal(), hc.astype(np.float64).lal(), longitude, latitude, polarization, self.frDetector) return TimeSeries(h_lal.data.data, delta_t=h_lal.deltaT, epoch=h_lal.epoch, dtype=np.float64, copy=False)
def get_strain_from_gwf_files( gwf_files: Dict[str, List[Union[str, bytes, os.PathLike]]], gps_start: int, window: int, original_sampling_rate: int = 4096, target_sampling_rate: int = 4096, as_pycbc_timeseries: bool = True, channel: str = 'GDS-CALIB_STRAIN', check_integrity: bool = True, ): assert isinstance(gps_start, int), 'time is not an int' assert isinstance(window, int), 'interval_width is not an int' assert isinstance(original_sampling_rate, int), 'original_sampling_rate is not an int' assert isinstance(target_sampling_rate, int), 'target_sampling_rate is not an int' assert (original_sampling_rate % target_sampling_rate) == 0, ( 'Invalid target_sampling_rate: Not a divisor of original_sampling_rate!' ) sampling_factor = int(original_sampling_rate / target_sampling_rate) samples = defaultdict(list) for ifo in gwf_files: detector_channel = f'{ifo}:{channel}' for file_path in gwf_files[ifo]: strain = read_frame( str(file_path), detector_channel, start_time=gps_start, end_time=gps_start + window, check_integrity=check_integrity, ) samples[ifo].append(strain[::sampling_factor]) samples[ifo] = np.ascontiguousarray(np.concatenate(samples[ifo])) if not as_pycbc_timeseries: return samples else: # Convert strain of both detectors to a TimeSeries object timeseries = { ifo: TimeSeries(initial_array=samples[ifo], delta_t=1.0 / target_sampling_rate, epoch=LIGOTimeGPS(gps_start)) for ifo in samples } return timeseries
def blendTimeSeries(hp0, hc0, mm, sample, time, t_opt): """ [DEPRECATED - use "blend"] Only dealing with real part, don't do hc calculations t_opt is length-5 array describing multiples of mm Returns length-5 array of TimeSeries (1 per blending) """ #{{{ from UseNRinDA import nr_waveform nrtool = nr_waveform() amp = TimeSeries(np.sqrt(hp0**2 + hc0**2), copy=True, delta_t=hp0.delta_t) max_a, max_a_index = amp.abs_max_loc() print("Waveform max = %e, located at %d" % (max_a, max_a_index)) amp_after_peak = amp amp_after_peak[:max_a_index] = 0 mtsun = lal.MTSUN_SI iA, vA = min(enumerate(amp_after_peak), key=lambda x: abs(x[1] - 0.01 * max_a)) iB, vB = min(enumerate(amp_after_peak), key=lambda x: abs(x[1] - 0.1 * max_a)) print(iA, iB) t = [ [ t_opt[0] * mm, 500 * mm, hp0.sample_times.data[iA] / mtsun, hp0.sample_times.data[iA] / mtsun + t_opt[3] * mm ], # Prayush's E [ t_opt[0] * mm, t_opt[1] * mm, hp0.sample_times.data[iA] / mtsun, hp0.sample_times.data[iA] / mtsun + t_opt[3] * mm ], [ t_opt[0] * mm, t_opt[1] * mm, hp0.sample_times.data[iB] / mtsun, hp0.sample_times.data[iB] / mtsun + t_opt[4] * mm ], [ t_opt[0] * mm, t_opt[2] * mm, hp0.sample_times.data[iA] / mtsun, hp0.sample_times.data[iA] / mtsun + t_opt[3] * mm ], [ t_opt[0] * mm, t_opt[2] * mm, hp0.sample_times.data[iB] / mtsun, hp0.sample_times.data[iB] / mtsun + t_opt[4] * mm ] ] hphc = [] #hphc.append(hp0) for i in range(len(t)): print(t[i]) hphc.append(nrtool.blending_function_Tukey(hp0=hp0,t=t[i],\ sample_rate=sample,time_length=time)) print("No of blending windows being tested = %d" % len(hphc)) return hphc
def setUp(self): # we'll use a sine wave time series to do the testing, with the # the segment length such that an interger number of cycles fit, so # we don't have to worry about boundary effects self.freq = 128 self.sample_rate = 4096 self.seglen = 1 ncycles = self.freq * self.seglen t = numpy.linspace(0, ncycles*2*numpy.pi, num=self.sample_rate*self.seglen, endpoint=False) self.time_series = TimeSeries(t, delta_t=1./self.sample_rate, epoch=0) self.tdsinx = numpy.sin(self.time_series) self.fdsinx = self.tdsinx.to_frequencyseries()
def project_wave(self, hp, hc, longitude, latitude, polarization): """Return the strain of a waveform as measured by the detector. Apply the time shift for the given detector relative to the assumed geocentric frame and apply the antenna patterns to the plus and cross polarizations. """ h_lal = lalsimulation.SimDetectorStrainREAL8TimeSeries( hp.astype(np.float64).lal(), hc.astype(np.float64).lal(), longitude, latitude, polarization, self.frDetector) return TimeSeries( h_lal.data.data, delta_t=h_lal.deltaT, epoch=h_lal.epoch, dtype=np.float64, copy=False)
def get_nrsur_modes(**params): """Generates NRSurrogate waveform mode-by-mode. All waveform parameters should be provided as keyword arguments. Recognized parameters are listed below. Unrecognized arguments are ignored. Parameters ---------- template: object An object that has attached properties. This can be used to substitute for keyword arguments. A common example would be a row in an xml table. approximant : str The approximant to generate. Must be one of the ``NRSur*`` models. {delta_t} {mass1} {mass2} {spin1x} {spin1y} {spin1z} {spin2x} {spin2y} {spin2z} {f_lower} {f_ref} {distance} {mode_array} Returns ------- dict : Dictionary of ``(l, m)`` -> ``(h_+, -h_x)`` ``TimeSeries``. """ laldict = _check_lal_pars(params) ret = lalsimulation.SimInspiralPrecessingNRSurModes( params['delta_t'], params['mass1']*lal.MSUN_SI, params['mass2']*lal.MSUN_SI, params['spin1x'], params['spin1y'], params['spin1z'], params['spin2x'], params['spin2y'], params['spin2z'], params['f_lower'], params['f_ref'], params['distance']*1e6*lal.PC_SI, laldict, getattr(lalsimulation, params['approximant']) ) hlms = {} while ret: hlm = TimeSeries(ret.mode.data.data, delta_t=ret.mode.deltaT, epoch=ret.mode.epoch) hlms[ret.l, ret.m] = (hlm.real(), hlm.imag()) ret = ret.next return hlms
def bandpass_pycbc(signal, sr, low_freq_cutoff, high_freq_cutoff, lowpass_order=8): from pycbc.types import TimeSeries ts = TimeSeries(signal, delta_t=1. / sr) import pycbc.filter ts = pycbc.filter.highpass(ts, low_freq_cutoff) import numpy return numpy.array( pycbc.filter.lowpass_fir(ts, high_freq_cutoff, lowpass_order))
def get_corecollapse_bounce(**kwargs): """ Generates core bounce and postbounce waveform by using principal component basis vectors from a .hdf file. The waveform parameters are the coefficients of the principal components and the distance. The number of principal components used can also be varied. """ try: principal_components = _pc_dict['principal_components'] except KeyError: with h5py.File(kwargs['principal_components_file'], 'r') as pc_file: principal_components = numpy.array(pc_file['principal_components']) _pc_dict['principal_components'] = principal_components if 'coefficients_array' in kwargs: coefficients_array = kwargs['coefficients_array'] else: coeffs_keys = [x for x in kwargs if x.startswith('coeff_')] coeffs_keys = numpy.sort(numpy.array(coeffs_keys)) coefficients_array = numpy.array([kwargs[x] for x in coeffs_keys]) no_of_pcs = int(kwargs['no_of_pcs']) coefficients_array = coefficients_array[:no_of_pcs] principal_components = principal_components[:no_of_pcs] pc_len = len(principal_components) assert len(coefficients_array) == pc_len distance = kwargs['distance'] mpc_conversion = 3.08567758128e+22 distance *= mpc_conversion strain = numpy.dot(coefficients_array, principal_components) / distance delta_t = kwargs['delta_t'] outhp = TimeSeries(strain, delta_t=delta_t) outhc = TimeSeries(numpy.zeros(len(strain)), delta_t=delta_t) return outhp, outhc
def calculate_acf(data): """ Calculates the autocorrelation function (ACF) and returns the one-sided ACF. ACF is estimated using \hat{R}(k) = \frac{1}{\left( n-k \right) \sigma^{2}} \sum_{t=1}^{n-k} \left( X_{t} - \mu \right) \left( X_{t+k} - \mu \right) Where \hat{R}(k) is the ACF, X_{t} is the data series at time t, \mu is the mean of X_{t}, and \sigma^{2} is the variance of X_{t}. Parameters ----------- data : {TimeSeries, numpy.array} A TimeSeries or numpy.array of data. Returns ------- acf : numpy.array If data is a TimeSeries then acf will be a TimeSeries of the one-sided ACF. Else acf is a numpy.array. """ # if given a TimeSeries instance then get numpy.array if isinstance(data, TimeSeries): y = data.numpy() else: y = data # subtract mean z = y - y.mean() # autocorrelate acf = numpy.correlate(z, z, mode="full") # take only the second half of the autocorrelation function acf = acf[acf.size / 2:] # normalize # note that ACF is function of k and we have a factor of n-k # at each k so the array here is a vectorized version of computing it acf /= (y.var() * numpy.arange(y.size, 0, -1)) # return a TimeSeries if input was a TimeSeries # otherwise return the numpy.array if isinstance(data, TimeSeries): return TimeSeries(acf, delta_t=data.delta_t) else: return acf
def read_store(fname, channel, start_time, end_time): """ Read time series data from hdf store Parameters ---------- fname: str Name of hdf store file channel: str Channel name to read start_time: int GPS time to start reading from end_time: int GPS time to end time series Returns ------- ts: pycbc.types.TimeSeries Time series containing the requested data """ fhandle = h5py.File(fname, 'r') if channel not in fhandle: raise ValueError('Could not find channel name {}'.format(channel)) # Determine which segment data lies in (can only read contiguous data now) starts = fhandle[channel]['segments']['start'][:] ends = fhandle[channel]['segments']['end'][:] diff = start_time - starts loc = numpy.where(diff >= 0)[0] sidx = loc[diff[loc].argmin()] stime = starts[sidx] etime = ends[sidx] if stime > start_time: raise ValueError("Cannot read data segment before {}".format(stime)) if etime < end_time: raise ValueError("Cannot read data segment past {}".format(etime)) data = fhandle[channel][str(sidx)] sample_rate = len(data) / (etime - stime) start = int((start_time - stime) * sample_rate) end = int((end_time - stime) * sample_rate) return TimeSeries(data[start:end], delta_t=1.0 / sample_rate, epoch=start_time)
def interpolate_complex_frequency(series, delta_f, zeros_offset=0, side='right'): """Interpolate complex frequency series to desired delta_f. Return a new complex frequency series that has been interpolated to the desired delta_f. Parameters ---------- series : FrequencySeries Frequency series to be interpolated. delta_f : float The desired delta_f of the output zeros_offset : optional, {0, int} Number of sample to delay the start of the zero padding side : optional, {'right', str} The side of the vector to zero pad Returns ------- interpolated series : FrequencySeries A new FrequencySeries that has been interpolated. """ new_n = int((len(series) - 1) * series.delta_f / delta_f + 1) old_N = int((len(series) - 1) * 2) new_N = int((new_n - 1) * 2) time_series = TimeSeries(zeros(old_N), delta_t=1.0 / (series.delta_f * old_N), dtype=real_same_precision_as(series)) ifft(series, time_series) time_series.roll(-zeros_offset) time_series.resize(new_N) if side == 'left': time_series.roll(zeros_offset + new_N - old_N) elif side == 'right': time_series.roll(zeros_offset) out_series = FrequencySeries(zeros(new_n), epoch=series.epoch, delta_f=delta_f, dtype=series.dtype) fft(time_series, out_series) return out_series
def extend_waveform_TimeSeries(wav, filter_N): # {{{ if len(wav) != filter_N: try: _wav = TimeSeries(np.zeros(filter_N), delta_t=wav.delta_t, dtype=real_same_precision_as(wav), epoch=wav._epoch) except MemoryError as merr: print(("Do you really want to allocate %d doubles?" % filter_N)) raise MemoryError(merr) _wav[:len(wav)] = wav else: _wav = wav return _wav
def setUp(self): numpy.random.seed(1023) self.size = pow(2, 12) self.data1 = numpy.array(numpy.random.rand(self.size), dtype=self.dtype) self.data2 = numpy.array(numpy.random.rand(self.size), dtype=self.dtype) # If the dtype is complex, we should throw in some complex values as well if self.dtype == numpy.complex64 or self.dtype == numpy.complex128: self.data1 += numpy.random.rand(self.size) * 1j self.data2 += numpy.random.rand(self.size) * 1j self.delta_t = .5 self.epoch = lal.LIGOTimeGPS(123456, 0) self.expected_data1 = TimeSeries(self.data1, dtype=self.dtype, epoch=self.epoch, delta_t=self.delta_t) self.expected_data2 = TimeSeries(self.data2, dtype=self.dtype, epoch=self.epoch, delta_t=self.delta_t)
def test_injection_presence(self): """Verify presence of signals at expected times""" injections = InjectionSet(self.inj_file.name) for det in self.detectors: for inj in self.injections: ts = TimeSeries(numpy.zeros(int(10 * self.sample_rate)), delta_t=1 / self.sample_rate, epoch=lal.LIGOTimeGPS(inj.end_time - 5), dtype=numpy.float64) injections.apply(ts, det.name) max_amp, max_loc = ts.abs_max_loc() # FIXME could test amplitude and time more precisely self.assertTrue(max_amp > 0 and max_amp < 1e-10) time_error = ts.sample_times.numpy()[max_loc] - inj.end_time self.assertTrue(abs(time_error) < 2 * self.earth_time)
def test_injection_absence(self): """Verify absence of signals outside known injection times""" clear_times = [ self.injections[0].end_time - 86400, self.injections[-1].end_time + 86400 ] injections = InjectionSet(self.inj_file.name) for det in self.detectors: for epoch in clear_times: ts = TimeSeries(numpy.zeros(int(10 * self.sample_rate)), delta_t=1 / self.sample_rate, epoch=lal.LIGOTimeGPS(epoch), dtype=numpy.float64) injections.apply(ts, det.name) max_amp, max_loc = ts.abs_max_loc() self.assertEqual(max_amp, 0)
def avg_cross_correlation(h1, l1, time, w=0.04): """Little change to the function by Creswell et al. The correlation would be estimated at time t in a window around the t instead of starting from the t """ # The time steps can be retrieved from the TimeSeries.sample_times # attribute, which is a pycbc.types.Array; the `.numpy()` converts that # to a numpy.array. h1_res_times = h1.sample_times.numpy() h1_res_strain = h1.numpy() l1_res_times = l1.sample_times.numpy() l1_res_strain = l1.numpy() fs = 1. / (h1_res_times[1] - h1_res_times[0]) min_indxt = numpy.where( abs(h1_res_times - (time - (w / 2.))) == abs(h1_res_times - (time - (w / 2.))).min())[0][0] max_indxt = numpy.where( abs(h1_res_times - (time + (w / 2.))) == abs(h1_res_times - (time + (w / 2.))).min())[0][0] deltatau = 0.01 tauind_min = int(-deltatau * fs) tauind_max = int(+deltatau * fs) tauind = numpy.arange(tauind_min, tauind_max) tau = tauind / fs corr = [] for i in tauind: corr.append( numpy.corrcoef( h1_res_strain[min_indxt + abs(tauind_min) + i:max_indxt - abs(tauind_max) + i], l1_res_strain[min_indxt + abs(tauind_min):max_indxt - abs(tauind_max)])[0][1]) corr = numpy.array(corr) return tau, TimeSeries(corr, epoch=tauind_min * h1.delta_t, delta_t=h1.delta_t)
def highpass(timeseries, frequency, filter_order=8, attenuation=0.1): """Return a new timeseries that is highpassed. Return a new time series that is highpassed above the `frequency`. Parameters ---------- Time Series: TimeSeries The time series to be high-passed. frequency: float The frequency below which is suppressed. filter_order: {8, int}, optional The order of the filter to use when high-passing the time series. attenuation: {0.1, float}, optional The attenuation of the filter. Returns ------- Time Series: TimeSeries A new TimeSeries that has been high-passed. Raises ------ TypeError: time_series is not an instance of TimeSeries. TypeError: time_series is not real valued """ if not isinstance(timeseries, TimeSeries): raise TypeError("Can only resample time series") if timeseries.kind is not 'real': raise TypeError("Time series must be real") lal_data = timeseries.lal() _highpass_func[timeseries.dtype](lal_data, frequency, 1 - attenuation, filter_order) return TimeSeries(lal_data.data.data, delta_t=lal_data.deltaT, dtype=timeseries.dtype, epoch=timeseries._epoch)
def to_timeseries(self, delta_t=None): """ Return the Fourier transform of this time series. Note that this assumes even length time series! Parameters ---------- delta_t : {None, float}, optional The time resolution of the returned series. By default the resolution is determined by length and delta_f of this frequency series. Returns ------- TimeSeries: The inverse fourier transform of this frequency series. """ from pycbc.fft import ifft from pycbc.types import TimeSeries, real_same_precision_as nat_delta_t = 1.0 / ((len(self)-1)*2) / self.delta_f if not delta_t: delta_t = nat_delta_t # add 0.5 to round integer tlen = int(1.0 / self.delta_f / delta_t + 0.5) flen = int(tlen / 2 + 1) if flen < len(self): raise ValueError("The value of delta_t (%s) would be " "undersampled. Maximum delta_t " "is %s." % (delta_t, nat_delta_t)) if not delta_t: tmp = self else: tmp = FrequencySeries(zeros(flen, dtype=self.dtype), delta_f=self.delta_f, epoch=self.epoch) tmp[:len(self)] = self[:] f = TimeSeries(zeros(tlen, dtype=real_same_precision_as(self)), delta_t=delta_t) ifft(tmp, f) f._delta_t = delta_t return f
def highpass_fir(timeseries, frequency, order, beta=5.0): """ Highpass filter the time series using an FIR filtered generated from the ideal response passed through a kaiser window (beta = 5.0) Parameters ---------- Time Series: TimeSeries The time series to be high-passed. frequency: float The frequency below which is suppressed. order: int Number of corrupted samples on each side of the time series beta: float Beta parameter of the kaiser window that sets the side lobe attenuation. """ k = frequency / float((int(1.0 / timeseries.delta_t) / 2)) coeff = scipy.signal.firwin(order * 2 + 1, k, window=('kaiser', beta), pass_zero=False) data = fir_zero_filter(coeff, timeseries) return TimeSeries(data, epoch=timeseries.start_time, delta_t=timeseries.delta_t)
def setUp(self): self.scheme = _scheme self.context = _context self.psd_len = 1024 self.psd_delta_f = 0.1 self.psd_low_freq_cutoff = 10. # generate 1/f noise for testing PSD estimation noise_size = 524288 sample_freq = 4096. delta_f = sample_freq / noise_size numpy.random.seed(132435) noise = numpy.random.normal(loc=0, scale=1, size=noise_size//2+1) + \ 1j * numpy.random.normal(loc=0, scale=1, size=noise_size//2+1) noise_model = 1. / numpy.linspace(1., 100., noise_size // 2 + 1) noise *= noise_model / numpy.sqrt(delta_f) / 2 noise[0] = noise[0].real noise_fs = FrequencySeries(noise, delta_f=delta_f) self.noise = TimeSeries(numpy.zeros(noise_size), delta_t=1. / sample_freq) ifft(noise_fs, self.noise)
def resample_to_delta_t(timeseries, delta_t): """Return a new time series that is resampled to the given delta_t. Only powers of two are currently supported. """ if not isinstance(timeseries, TimeSeries): raise TypeError("Can only resample time series") if timeseries.kind is not 'real': raise TypeError("Time series must be real") if timeseries.delta_t == delta_t: return timeseries * 1 lal_data = timeseries.lal() _resample_func[timeseries.dtype](lal_data, delta_t) return TimeSeries(lal_data.data.data, delta_t=lal_data.deltaT, dtype=timeseries.dtype, epoch=timeseries._epoch)
def test_waveform(**args): flow = args['f_lower'] # Required parameter dt = args['delta_t'] # Required parameter fpeak = args['fpeak'] # A new parameter for my model t = numpy.arange(0, 10, dt) f = t / t.max() * (fpeak - flow) + flow a = t wf = numpy.exp(2.0j * numpy.pi * f * t) * a # Return product should be a pycbc time series in this case for # each GW polarization # # # Note that by convention, the time at 0 is a fiducial reference. # For CBC waveforms, this would be set to where the merger occurs offset = -len(t) * dt wf = TimeSeries(wf, delta_t=dt, epoch=offset) return wf.real(), wf.imag()
def test_chirp(self): ### use a chirp as a signal sigt = TimeSeries(self.sig1, self.del_t) sig_tilde = make_frequency_series(sigt) del_f = sig_tilde.get_delta_f() psd = FrequencySeries(self.Psd, del_f) flow = self.low_frequency_cutoff with _context: hautocor, hacorfr, hnrm = matched_filter_core(self.htilde, self.htilde, psd=psd, \ low_frequency_cutoff=flow, high_frequency_cutoff=self.fmax) snr, cor, nrm = matched_filter_core(self.htilde, sig_tilde, psd=psd, \ low_frequency_cutoff=flow, high_frequency_cutoff=self.fmax) hacor = Array(hautocor.real(), copy=True) indx = Array(np.array([352250, 352256, 352260])) snr = snr * nrm with _context: dof, achi_list = autochisq_from_precomputed(snr, cor, hacor, stride=3, num_points=20, \ indices=indx) obt_snr = achi_list[1, 1] obt_ach = achi_list[1, 2] self.assertTrue(obt_snr > 10.0 and obt_snr < 12.0) self.assertTrue(obt_ach < 1.e-3) self.assertTrue(achi_list[0, 2] > 20.0) self.assertTrue(achi_list[2, 2] > 20.0) with _context: dof, achi_list = autochisq(self.htilde, sig_tilde, psd, stride=3, num_points=20, \ low_frequency_cutoff=flow, high_frequency_cutoff=self.fmax, max_snr=True) self.assertTrue(obt_snr == achi_list[0, 1]) self.assertTrue(obt_ach == achi_list[0, 2]) for i in xrange(1, len(achi_list)): self.assertTrue(achi_list[i, 2] > 4.0)