def matched_filter_real(template, psd): fdfilter = matched_filter_real_fd(template, psd) tdfilter = lal.CreateREAL8TimeSeries(None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit, 2 * (len(fdfilter.data.data) - 1)) plan = CreateReverseREAL8FFTPlan(len(tdfilter.data.data), 0) lal.REAL8FreqTimeFFT(tdfilter, fdfilter, plan) return tdfilter
def colored_noise(epoch, duration, sample_rate, psd): """Generate a REAL8TimeSeries containing duration seconds of colored Gaussian noise at the given sample rate, with the start time given by epoch. psd should be an instance of REAL8FrequencySeries containing a discretely sample power spectrum with f0=0, deltaF=1/duration, and a length of ((duration * sample_rate) // 2 + 1) samples. """ data_length = duration * sample_rate plan = CreateReverseREAL8FFTPlan(data_length, 0) x = lal.CreateREAL8TimeSeries( None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit, data_length) xf = lal.CreateCOMPLEX16FrequencySeries( None, epoch, 0, 1 / duration, lal.DimensionlessUnit, data_length // 2 + 1) white_noise = (np.random.randn(len(xf.data.data)) + np.random.randn(len(xf.data.data)) * 1j) # On line 1288 of lal's AverageSpectrum.c, in the code comments for # XLALWhitenCOMPLEX8FrequencySeries, it says that according to the LAL # conventions a whitened frequency series should consist of bins whose # real and imaginary parts each have a variance of 1/2. white_noise /= np.sqrt(2) # The factor of sqrt(2 * psd.deltaF) comes from the value of 'norm' on # line 1362 of AverageSpectrum.c. xf.data.data = white_noise * np.sqrt(psd.data.data / (2 * psd.deltaF)) # Detrend the data: no DC component. xf.data.data[0] = 0 # Return to time domain. lal.REAL8FreqTimeFFT(x, xf, plan) # Copy over metadata. x.epoch = epoch x.sampleUnits = lal.StrainUnit # Done. return x
def analyze_event(P_list, indx_event, data_dict, psd_dict, fmax, opts, inv_spec_trunc_Q=inv_spec_trunc_Q, T_spec=T_spec): nEvals = 0 P = P_list[indx_event] # Precompute t_window = 0.15 rholms_intp, cross_terms, cross_terms_V, rholms, rest = factored_likelihood.PrecomputeLikelihoodTerms( fiducial_epoch, t_window, P, data_dict, psd_dict, opts.l_max, fmax, False, inv_spec_trunc_Q, T_spec, NR_group=NR_template_group, NR_param=NR_template_param, use_external_EOB=opts.use_external_EOB, nr_lookup=opts.nr_lookup, nr_lookup_valid_groups=opts.nr_lookup_group, perturbative_extraction=opts.nr_perturbative_extraction, use_provided_strain=opts.nr_use_provided_strain, hybrid_use=opts.nr_hybrid_use, hybrid_method=opts.nr_hybrid_method, ROM_group=opts.rom_group, ROM_param=opts.rom_param, ROM_use_basis=opts.rom_use_basis, verbose=opts.verbose, quiet=not opts.verbose, ROM_limit_basis_size=opts.rom_limit_basis_size_to, no_memory=opts.no_memory, skip_interpolation=opts.vectorized) # Only allocate the FFT plans ONCE ifo0 = psd_dict.keys()[0] npts = data_dict[ifo0].data.length print(" Allocating FFT forward, reverse plans ", npts) fwdplan = lal.CreateForwardREAL8FFTPlan(npts, 0) revplan = lal.CreateReverseREAL8FFTPlan(npts, 0) for ifo in psd_dict: # Plot PSDs plt.figure(99) # PSD figure) fvals = psd_dict[ifo].f0 + np.arange( psd_dict[ifo].data.length) * psd_dict[ifo].deltaF plt.plot(fvals, np.log10(np.sqrt(psd_dict[ifo].data.data)), label=ifo) plt.figure(88) plt.plot(fvals, fvals**(-14. / 6.) / psd_dict[ifo].data.data) plt.figure(1) # Plot inverse spectrum filters # - see lalsimutils code for inv_spec_trunc_Q , copied verbatim plt.figure(98) IP_here = lalsimutils.ComplexOverlap(P.fmin, fmax, 1. / 2 / P.deltaT, P.deltaF, psd_dict[ifo], False, inv_spec_trunc_Q, T_spec) WFD = lal.CreateCOMPLEX16FrequencySeries('FD root inv. spec.', lal.LIGOTimeGPS(0.), 0., IP_here.deltaF, lal.DimensionlessUnit, IP_here.len1side) WTD = lal.CreateREAL8TimeSeries('TD root inv. spec.', lal.LIGOTimeGPS(0.), 0., IP_here.deltaT, lal.DimensionlessUnit, IP_here.len2side) print(ifo, IP_here.len2side) # if not(fwdplan is None): WFD.data.data[:] = np.sqrt(IP_here.weights) # W_FD is 1/sqrt(S_n(f)) WFD.data.data[0] = WFD.data.data[-1] = 0. # zero 0, f_Nyq bins lal.REAL8FreqTimeFFT(WTD, WFD, revplan) # IFFT to TD tvals = IP_here.deltaT * np.arange(IP_here.len2side) plt.plot(tvals, np.log10(np.abs(WTD.data.data)), label=ifo) # Plot Q's plt.figure(1) plt.clf() for mode in rholms[ifo]: Q_here = rholms[ifo][mode] tvals = lalsimutils.evaluate_tvals(Q_here) - P.tref plt.plot(tvals, np.abs(Q_here.data.data), label=ifo + str(mode[0]) + "," + str(mode[1])) plt.legend() plt.xlabel("t (s)") plt.xlim(-0.1, 0.1) plt.xlabel("$Q_{lm}$") plt.title(ifo) plt.savefig(ifo + "_Q.png") plt.figure(99) plt.legend() plt.xlabel("f(Hz)") plt.ylabel(r'$\sqrt{S_h}$') plt.ylim(-24, -21) plt.savefig("PSD_plots.png") plt.xlim(5, 800) plt.savefig("PSD_plots_detail.png") plt.xlim(10, 400) plt.ylim(-23.5, -22) plt.savefig("PSD_plots_detail_fine.png") plt.figure(98) plt.legend() plt.xlabel("t (s)") plt.savefig("PSD_inv_plots.png") plt.figure(88) plt.legend() plt.xlabel("f (Hz)") plt.ylabel(r'$(S_h f^{15/6})^{-1}$') plt.savefig("PSD_weight_f.png")