def create_injection_list(N_inj, srate, start_GPS, end_GPS, theta_range = [[10,100],[10,100],[-0.8,0.8],[-0.8,0.8],[40,400],[0.,np.pi],[0.,2*np.pi]], datafile = None): """ Creates a list of injections. Each injection is a dictionary with entries: "WF": a WF array plus of variable length "srate": a sampling rate for the WF "GPS": GPS time for the merger "theta": a 7 dimensional array holding params of the WF [m1,m2,s1,s2,d_L, iota, phi] """ if datafile is not None: data = np.squeeze(pd.read_csv(datafile, skiprows =3).to_numpy()) g = gen.GW_generator(0) inj_list = [] theta_range = np.array(theta_range) for i in range(N_inj): inj = {} theta = np.random.uniform(*theta_range.T,size = (7,)) #theta = [35.,30.,0.,0., 440., 0., 1.] t_min = np.random.uniform(-10,-6) t_grid = np.linspace(t_min, 1., int((1.-t_min)*srate)) h_p, h_c = g.get_WF(theta, t_grid) #computing antenna patterns sky_loc = np.random.uniform(0.,np.pi,size = (3,)) F_p, F_c = antenna_patterns(*sky_loc) h = h_p *F_p + h_c*F_c D_eff = theta[4]/np.sqrt(F_p**2 *( (1+np.cos(theta[5])**2) /2.)**2 + ( F_c*np.cos(theta[5]) )**2) #https://arxiv.org/pdf/1603.02444.pdf #computing SNR #FIXME: I have serious doubt that the SNR is computed correctly #FIXME: NUmbers look fine but I see a peak in the SNR without injection!! What the f**k?!?!?! #TODO: smooth WF switching on!! #for SNR you can check: # https://gwpy.github.io/docs/stable/examples/timeseries/pycbc-snr.html # https://git.ligo.org/lscsoft/gstlal/-/blob/master/gstlal-inspiral/bin/gstlal_inspiral_injection_snr if datafile is not None: h_time_series = pycbc.types.timeseries.TimeSeries(h.astype(np.float64), 1./srate) data_time_series = pycbc.types.timeseries.TimeSeries(data.astype(np.float64), 1./srate) #data_time_series[0:len(h_time_series)] += h_time_series data_time_series = TimeSeries.from_pycbc(data_time_series) data_time_series = data_time_series.highpass(15) psd = data_time_series.psd(len(h_time_series)/srate, 5).to_pycbc() data_time_series = data_time_series.to_pycbc()[len(data_time_series)-len(h_time_series)-2000:-2000] #data_time_series = pycbc.types.timeseries.TimeSeries(np.random.normal(0,1,len(data_time_series)).astype(np.float64), 1./srate) #h_time_series = pycbc.types.timeseries.TimeSeries(np.random.normal(0,1,len(h_time_series)).astype(np.float64), 1./srate) SNR_ts = pycbc.filter.matchedfilter.matched_filter(h_time_series/len(h_time_series), data_time_series, psd, low_frequency_cutoff=20., high_frequency_cutoff = 2048) #TD template should be divided by its length for FFT purposes! np.fft is weird and doesn't normalize stuff SNR_ts = SNR_ts[100:-100] SNR = np.max(np.abs(np.array(SNR_ts))) #print("Theta | Injection SNR: ", theta, SNR) #plt.plot(data_time_series) #plt.plot(h_time_series) #plt.plot(np.abs(np.array(SNR_ts))) #plt.plot(np.log(psd)) #plt.show() else: SNR = None inj['theta'] = theta inj['skyloc'] = sky_loc inj['D_eff'] = D_eff inj['srate'] = srate inj['GPS'] = int(start_GPS) inj['time'] = np.random.uniform(.3, float(end_GPS-start_GPS)) inj['WF'] = h inj['SNR'] = SNR inj_list.append(inj) return inj_list
mass2=32, f_lower=20, f_final=2048, delta_f=psd.df.value) # At this point we are ready to calculate the SNR, so we import the # :func:`pycbc.filter.matched_filter # <pycbc.filter.matchedfilter.matched_filter>` method, and pass it # our template, the data, and the PSD: from pycbc.filter import matched_filter snr = matched_filter(hp, zoom.to_pycbc(), psd=psd.to_pycbc(), low_frequency_cutoff=15) snrts = TimeSeries.from_pycbc(snr).abs() # .. note:: # # Here we have used the :meth:`~TimeSeries.to_pycbc` methods of the # `~gwpy.timeseries.TimeSeries` and `~gwpy.frequencyseries.FrequencySeries` # objects to convert from GWpy objects to something that PyCBC functions # can understand, and then used the :meth:`~TimeSeries.from_pycbc` method # to convert back to a GWpy object. # We can plot the SNR `TimeSeries` around the region of interest: plot = snrts.plot() ax = plot.gca() ax.set_xlim(1126259461, 1126259463) ax.set_epoch(1126259462.427) ax.set_ylabel('Signal-to-noise ratio (SNR)')
# template `~pycbc.types.frequencyseries.FrequencySeries`: from pycbc.waveform import get_fd_waveform hp, _ = get_fd_waveform(approximant="IMRPhenomD", mass1=40, mass2=32, f_lower=20, f_final=2048, delta_f=psd.df.value) # At this point we are ready to calculate the SNR, so we import the # :func:`~pycbc.filter.matched_filter` method, and pass it our template, # the data, and the PSD, using the :meth:`~TimeSeries.to_pycbc` methods of # the `TimeSeries` and `~gwpy.frequencyseries.FrequencySeries` objects: import numpy from pycbc.filter import matched_filter snr = matched_filter(hp, zoom.to_pycbc(), psd=psd.to_pycbc(), low_frequency_cutoff=15) snrts = TimeSeries.from_pycbc(snr).abs() # We can plot the SNR `TimeSeries` around the region of interest: plot = snrts.plot() ax = plot.gca() ax.set_xlim(1126259461, 1126259463) ax.set_epoch(1126259462.427) ax.set_ylabel('Signal-to-noise ratio (SNR)') ax.set_title('LIGO-Hanford signal-correlation for GW150914') plot.show() # We can clearly see a large spike (above 17!) at the time of the GW150914 # signal! # This is, in principle, how the full, blind, CBC search is performed, using # all of the available data, and a bank of tens of thousand of signal models.