def _vecdiff(htilde, hinterp, fmin, fmax, psd=None): return abs(filter.overlap_cplx(htilde, htilde, low_frequency_cutoff=fmin, high_frequency_cutoff=fmax, normalized=False, psd=psd) - filter.overlap_cplx(htilde, hinterp, low_frequency_cutoff=fmin, high_frequency_cutoff=fmax, normalized=False, psd=psd))
def _vecdiff(htilde, hinterp, fmin, fmax): return abs(filter.overlap_cplx(htilde, htilde, low_frequency_cutoff=fmin, high_frequency_cutoff=fmax, normalized=False) - filter.overlap_cplx(htilde, hinterp, low_frequency_cutoff=fmin, high_frequency_cutoff=fmax, normalized=False))
def template_overlaps(bank_filters, template, psd, low_frequency_cutoff): """ This functions calculates the overlaps between the template and the bank veto templates. Parameters ---------- bank_filters: List of FrequencySeries template: FrequencySeries psd: FrequencySeries low_frequency_cutoff: float Returns ------- overlaps: List of complex overlap values. """ overlaps = [] template_ow = template / psd for bank_template in bank_filters: overlap = overlap_cplx(template_ow, bank_template, low_frequency_cutoff=low_frequency_cutoff, normalized=False) norm = sqrt(1 / template.sigmasq(psd) / bank_template.sigmasq(psd)) overlaps.append(overlap * norm) if (abs(overlaps[-1]) > 0.99): errMsg = "Overlap > 0.99 between bank template and filter. " errMsg += "This bank template will not be used to calculate " errMsg += "bank chisq for this filter template. The expected " errMsg += "value will be added to the chisq to account for " errMsg += "the removal of this template.\n" errMsg += "Masses of filter template: %e %e\n" \ %(template.params.mass1, template.params.mass2) errMsg += "Masses of bank filter template: %e %e\n" \ %(bank_template.params.mass1, bank_template.params.mass2) errMsg += "Overlap: %e" %(abs(overlaps[-1])) logging.debug(errMsg) return overlaps
def test_filtering(self): idx = self.idx jdx = self.jdx #w1 = self.wps_list[idx] #w2 = self.wps_list[jdx] #stilde = get_waveform(w1, self.low_freq_filter-1, # self.sample_rate, self.filter_N, # self.sample_rate) #try: # stilde.save('data/skymaxtest_stilde_%d.hdf' % idx) #except: # pass stilde = load_frequencyseries(self.dataDir + \ 'skymaxtest_stilde_%d.hdf' % idx) s_norm = sigmasq(stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) stilde /= sqrt(float(s_norm)) stilde *= 100 #hplus, hcross = get_waveform(w2, self.low_freq_filter-1, # self.sample_rate, self.filter_N, # self.sample_rate, sky_max_template=True) #try: # hplus.save('data/skymaxtest_hplus_%d.hdf' % jdx) # hcross.save('data/skymaxtest_hcross_%d.hdf' % jdx) #except: # pass hplus = load_frequencyseries(self.dataDir + \ 'skymaxtest_hplus_%d.hdf' % jdx) hcross = load_frequencyseries(self.dataDir + \ 'skymaxtest_hcross_%d.hdf' % jdx) hplus.f_lower = self.low_freq_filter hplus.params = random.randint(0,100000000000) hcross.f_lower = self.low_freq_filter hcross.params = random.randint(0,100000000000) hp_norm = sigmasq(hplus, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) hc_norm = sigmasq(hcross, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) hplus /= sqrt(float(hp_norm)) hcross /= sqrt(float(hc_norm)) hpc_corr = overlap_cplx(hplus, hcross, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, normalized=False) hpc_corr_R = real(hpc_corr) I_plus, corr_plus, n_plus = matched_filter_core\ (hplus, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) # FIXME: Remove the deepcopies before merging with master I_plus = copy.deepcopy(I_plus) corr_plus = copy.deepcopy(corr_plus) I_cross, corr_cross, n_cross = matched_filter_core\ (hcross, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_cross = copy.deepcopy(I_cross) corr_cross = copy.deepcopy(corr_cross) I_plus = I_plus * n_plus I_cross = I_cross * n_cross IPM = abs(I_plus.data).argmax() ICM = abs(I_cross.data).argmax() self.assertAlmostEqual(abs(I_plus[IPM]), expected_results[idx][jdx]['Ip_snr']) self.assertAlmostEqual(angle(I_plus[IPM]), expected_results[idx][jdx]['Ip_angle']) self.assertEqual(IPM, expected_results[idx][jdx]['Ip_argmax']) self.assertAlmostEqual(abs(I_cross[ICM]), expected_results[idx][jdx]['Ic_snr']) self.assertAlmostEqual(angle(I_cross[ICM]), expected_results[idx][jdx]['Ic_angle']) self.assertEqual(ICM, expected_results[idx][jdx]['Ic_argmax']) #print "expected_results[{}][{}]['Ip_snr'] = {}" .format(idx,jdx,abs(I_plus[IPM])) #print "expected_results[{}][{}]['Ip_angle'] = {}".format(idx,jdx,angle(I_plus[IPM])) #print "expected_results[{}][{}]['Ip_argmax'] = {}".format(idx,jdx, IPM) #print "expected_results[{}][{}]['Ic_snr'] = {}" .format(idx,jdx,abs(I_cross[ICM])) #print "expected_results[{}][{}]['Ic_angle'] = {}".format(idx,jdx,angle(I_cross[ICM])) #print "expected_results[{}][{}]['Ic_argmax'] = {}".format(idx,jdx, ICM) det_stat_prec = compute_max_snr_over_sky_loc_stat\ (I_plus, I_cross, hpc_corr_R, hpnorm=1., hcnorm=1., thresh=0.1, analyse_slice=slice(0,len(I_plus.data))) det_stat_hom = compute_max_snr_over_sky_loc_stat_no_phase\ (I_plus, I_cross, hpc_corr_R, hpnorm=1., hcnorm=1., thresh=0.1, analyse_slice=slice(0,len(I_plus.data))) idx_max_prec = argmax(det_stat_prec.data) idx_max_hom = argmax(det_stat_hom.data) max_ds_prec = det_stat_prec[idx_max_prec] max_ds_hom = det_stat_hom[idx_max_hom] uvals_prec, _ = compute_u_val_for_sky_loc_stat\ (I_plus.data, I_cross.data, hpc_corr_R, indices=[idx_max_prec], hpnorm=1., hcnorm=1.) uvals_hom, _ = compute_u_val_for_sky_loc_stat_no_phase\ (I_plus.data, I_cross.data, hpc_corr_R, indices=[idx_max_hom], hpnorm=1., hcnorm=1.) ht = hplus * uvals_hom[0] + hcross ht_norm = sigmasq(ht, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) ht /= sqrt(float(ht_norm)) ht.f_lower = self.low_freq_filter ht.params = random.randint(0,100000000000) I_t, corr_t, n_t = matched_filter_core\ (ht, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_t = I_t * n_t self.assertAlmostEqual(abs(real(I_t.data[idx_max_hom])), max_ds_hom) self.assertEqual(abs(real(I_t.data[idx_max_hom])), max(abs(real(I_t.data)))) chisq, _ = self.power_chisq.values\ (corr_t, array([max_ds_hom]) / n_plus, n_t, self.psd, array([idx_max_hom]), ht) ht = hplus * uvals_prec[0] + hcross ht_norm = sigmasq(ht, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) ht /= sqrt(float(ht_norm)) ht.f_lower = self.low_freq_filter ht.params = random.randint(0,100000000000) I_t, corr_t, n_t = matched_filter_core\ (ht, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_t = I_t * n_t chisq, _ = self.power_chisq.values\ (corr_t, array([max_ds_prec]) / n_plus, n_t, self.psd, array([idx_max_prec]), ht) self.assertAlmostEqual(abs(I_t.data[idx_max_prec]), max_ds_prec) self.assertEqual(idx_max_prec, abs(I_t.data).argmax()) self.assertTrue(chisq < 1E-4)
def test_filtering(self): idx = self.idx jdx = self.jdx #w1 = self.wps_list[idx] #w2 = self.wps_list[jdx] #stilde = get_waveform(w1, self.low_freq_filter-1, # self.sample_rate, self.filter_N, # self.sample_rate) #try: # stilde.save('data/skymaxtest_stilde_%d.hdf' % idx) #except: # pass stilde = load_frequencyseries(self.dataDir + \ 'skymaxtest_stilde_%d.hdf' % idx) s_norm = sigmasq(stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) stilde /= sqrt(float(s_norm)) stilde *= 100 #hplus, hcross = get_waveform(w2, self.low_freq_filter-1, # self.sample_rate, self.filter_N, # self.sample_rate, sky_max_template=True) #try: # hplus.save('data/skymaxtest_hplus_%d.hdf' % jdx) # hcross.save('data/skymaxtest_hcross_%d.hdf' % jdx) #except: # pass hplus = load_frequencyseries(self.dataDir + \ 'skymaxtest_hplus_%d.hdf' % jdx) hcross = load_frequencyseries(self.dataDir + \ 'skymaxtest_hcross_%d.hdf' % jdx) hplus.f_lower = self.low_freq_filter hplus.params = random.randint(0, 100000000000) hcross.f_lower = self.low_freq_filter hcross.params = random.randint(0, 100000000000) hp_norm = sigmasq(hplus, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) hc_norm = sigmasq(hcross, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) hplus /= sqrt(float(hp_norm)) hcross /= sqrt(float(hc_norm)) hpc_corr = overlap_cplx(hplus, hcross, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, normalized=False) hpc_corr_R = real(hpc_corr) I_plus, corr_plus, n_plus = matched_filter_core\ (hplus, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) # FIXME: Remove the deepcopies before merging with master I_plus = copy.deepcopy(I_plus) corr_plus = copy.deepcopy(corr_plus) I_cross, corr_cross, n_cross = matched_filter_core\ (hcross, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_cross = copy.deepcopy(I_cross) corr_cross = copy.deepcopy(corr_cross) I_plus = I_plus * n_plus I_cross = I_cross * n_cross IPM = abs(I_plus.data).argmax() ICM = abs(I_cross.data).argmax() self.assertAlmostEqual(abs(I_plus[IPM]), expected_results[idx][jdx]['Ip_snr']) self.assertAlmostEqual(angle(I_plus[IPM]), expected_results[idx][jdx]['Ip_angle']) self.assertEqual(IPM, expected_results[idx][jdx]['Ip_argmax']) self.assertAlmostEqual(abs(I_cross[ICM]), expected_results[idx][jdx]['Ic_snr']) self.assertAlmostEqual(angle(I_cross[ICM]), expected_results[idx][jdx]['Ic_angle']) self.assertEqual(ICM, expected_results[idx][jdx]['Ic_argmax']) #print "expected_results[{}][{}]['Ip_snr'] = {}" .format(idx,jdx,abs(I_plus[IPM])) #print "expected_results[{}][{}]['Ip_angle'] = {}".format(idx,jdx,angle(I_plus[IPM])) #print "expected_results[{}][{}]['Ip_argmax'] = {}".format(idx,jdx, IPM) #print "expected_results[{}][{}]['Ic_snr'] = {}" .format(idx,jdx,abs(I_cross[ICM])) #print "expected_results[{}][{}]['Ic_angle'] = {}".format(idx,jdx,angle(I_cross[ICM])) #print "expected_results[{}][{}]['Ic_argmax'] = {}".format(idx,jdx, ICM) det_stat_prec = compute_max_snr_over_sky_loc_stat\ (I_plus, I_cross, hpc_corr_R, hpnorm=1., hcnorm=1., thresh=0.1, analyse_slice=slice(0,len(I_plus.data))) det_stat_hom = compute_max_snr_over_sky_loc_stat_no_phase\ (I_plus, I_cross, hpc_corr_R, hpnorm=1., hcnorm=1., thresh=0.1, analyse_slice=slice(0,len(I_plus.data))) idx_max_prec = argmax(det_stat_prec.data) idx_max_hom = argmax(det_stat_hom.data) max_ds_prec = det_stat_prec[idx_max_prec] max_ds_hom = det_stat_hom[idx_max_hom] uvals_prec, _ = compute_u_val_for_sky_loc_stat\ (I_plus.data, I_cross.data, hpc_corr_R, indices=[idx_max_prec], hpnorm=1., hcnorm=1.) uvals_hom, _ = compute_u_val_for_sky_loc_stat_no_phase\ (I_plus.data, I_cross.data, hpc_corr_R, indices=[idx_max_hom], hpnorm=1., hcnorm=1.) ht = hplus * uvals_hom[0] + hcross ht_norm = sigmasq(ht, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) ht /= sqrt(float(ht_norm)) ht.f_lower = self.low_freq_filter ht.params = random.randint(0, 100000000000) I_t, corr_t, n_t = matched_filter_core\ (ht, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_t = I_t * n_t self.assertAlmostEqual(abs(real(I_t.data[idx_max_hom])), max_ds_hom) self.assertEqual(abs(real(I_t.data[idx_max_hom])), max(abs(real(I_t.data)))) chisq, _ = self.power_chisq.values\ (corr_t, array([max_ds_hom]) / n_plus, n_t, self.psd, array([idx_max_hom]), ht) ht = hplus * uvals_prec[0] + hcross ht_norm = sigmasq(ht, psd=self.psd, low_frequency_cutoff=self.low_freq_filter) ht /= sqrt(float(ht_norm)) ht.f_lower = self.low_freq_filter ht.params = random.randint(0, 100000000000) I_t, corr_t, n_t = matched_filter_core\ (ht, stilde, psd=self.psd, low_frequency_cutoff=self.low_freq_filter, h_norm=1.) I_t = I_t * n_t chisq, _ = self.power_chisq.values\ (corr_t, array([max_ds_prec]) / n_plus, n_t, self.psd, array([idx_max_prec]), ht) self.assertAlmostEqual(abs(I_t.data[idx_max_prec]), max_ds_prec) self.assertEqual(idx_max_prec, abs(I_t.data).argmax()) self.assertTrue(chisq < 1E-4)
def align_waveforms_suboptimally(hplus1, hcross1, hplus2, hcross2, psd='aLIGOZeroDetHighPower', low_frequency_cutoff=None, high_frequency_cutoff=None, tsign=1, phsign=1, verify=True, trim_leading=False, trim_trailing=False, verbose=False): # Cast into time-series h_plus1 = TimeSeries(hplus1, epoch=hplus1._epoch, delta_t=hplus1.delta_t, dtype=hplus1.dtype) h_cross1 = TimeSeries(hcross1, epoch=hplus1._epoch, delta_t=hplus1.delta_t, dtype=hplus1.dtype) h_plus2 = TimeSeries(hplus2, epoch=hplus2._epoch, delta_t=hplus2.delta_t, dtype=hplus2.dtype) h_cross2 = TimeSeries(hcross2, epoch=hplus2._epoch, delta_t=hplus2.delta_t, dtype=hplus2.dtype) # # Ensure both input hplus vectors are equal in length if len(hplus2) > len(hplus1): h_plus1.append_zeros(len(hplus2) - len(hplus1)) h_cross1.append_zeros(len(hplus2) - len(hplus1)) elif len(hplus2) < len(hplus1): h_plus2.append_zeros(len(hplus1) - len(hplus2)) h_cross2.append_zeros(len(hplus1) - len(hplus2)) # htilde = make_frequency_series(h_plus1) stilde = make_frequency_series(h_plus2) # if high_frequency_cutoff == None: high_frequency_cutoff = 1. / h_plus1.delta_t / 2. # if psd == None: raise IOError("Need compatible psd [or name] as input!") elif type(psd) == str: psd_name = psd psd = from_string(psd_name, len(htilde), htilde.delta_f, low_frequency_cutoff) # # Determine the phase and time shifts for optimal match snr, corr, snr_norm = matched_filter_core( htilde, stilde, # h_plus1, h_plus2, psd, low_frequency_cutoff, high_frequency_cutoff, None) max_snr, max_id = snr.abs_max_loc() if max_id != 0: t_shift = snr.delta_t * (len(snr) - max_id) else: t_shift = snr.delta_t * max_id ph_shift = np.angle(snr[max_id]) - 0.24850315030 - 0.0465881735639 # if verbose: print(("max_id = %d, id_shift = %d" % (max_id, int(t_shift / snr.delta_t)))) print(("t_shift = %f,\n ph_shift = %f" % (t_shift, ph_shift))) # # print(OVERLAPS if verbose: print(("Overlap BEFORE ALIGNMENT:", overlap_cplx(h_plus1, h_plus2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff, normalized=True))) print(("Match BEFORE ALIGNMENT:", match(h_plus1, h_plus2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff))) # Shift whichever needs to be shifted to future time. # Shifting back in time is tricky. if t_shift >= 0: hp2, hc2 = shift_waveform_phase_time(h_plus2, h_cross2, tsign * t_shift, phsign * ph_shift, verbose=verbose) else: hp2, hc2 = shift_waveform_phase_time(h_plus2, h_cross2, tsign * t_shift, phsign * ph_shift, verbose=verbose) # # Ensure both input hplus vectors are equal in length if len(h_plus1) > len(hp2): hp2.append_zeros(len(h_plus1) - len(hp2)) elif len(h_plus1) < len(hp2): h_plus1.append_zeros(len(hp2) - len(h_plus1)) if verbose: htilde = make_frequency_series(h_plus1) psd = from_string(psd_name, len(htilde), htilde.delta_f, low_frequency_cutoff) print(("Overlap AFTER ALIGNMENT:", overlap_cplx(h_plus1, hp2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff, normalized=True))) print(("Match AFTER ALIGNMENT:", match(h_plus1, hp2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff))) if verify: # print("Verifying time alignment...") # Determine the phase and time shifts for optimal match snr, corr, snr_norm = matched_filter_core( # htilde, stilde, h_plus1, hp2, psd, low_frequency_cutoff, high_frequency_cutoff, None) max_snr, max_id = snr.abs_max_loc() print(("Post-Alignment Index of MAX SNR (should be 0 or 1 or %d): %d" % (len(snr) - 1, max_id))) print(("Length of whole SNR time-series: ", len(snr))) if max_id != 0 and max_id != 1 and max_id != ( len(snr) - 1) and max_id != (len(snr) - 2): # raise RuntimeError( "Warning: ALIGNMENT NOT CORRECT (see above)" ) print("Warning: ALIGNMENT NOT CORRECT (see above)") else: print("Alignment in time correct..") # print("Verifying phase alignment...") ph_shift = np.angle(snr[max_id]) if ph_shift != 0: print("Warning: Phasing alignment possibly incorrect.") print(("dphi, dphi+pi, dphi-pi: ", ph_shift, ph_shift + np.pi, ph_shift - np.pi)) print(("dphi/pi, dphi*pi: ", ph_shift / np.pi, ph_shift * np.pi)) # # if trim_trailing: hp1 = trim_trailing_zeros(hp1) hc1 = trim_trailing_zeros(hc1) hp2 = trim_trailing_zeros(hp2) hc2 = trim_trailing_zeros(hc2) if trim_leading: hp1 = trim_leading_zeros(hp1) hc1 = trim_leading_zeros(hc1) hp2 = trim_leading_zeros(hp2) hc2 = trim_leading_zeros(hc2) # return hplus1, hcross1, hp2, hc2
def align_waveforms_optimally(hplus1, hcross1, hplus2, hcross2, psd='aLIGOZeroDetHighPower', low_frequency_cutoff=None, high_frequency_cutoff=None, tsign=1, phsign=-1, verify=True, phase_tolerance=1e-3, overlap_tolerance=1e-3, trim_leading=False, trim_trailing=False, verbose=False): """ Align waveforms such that their inner product (noise weighted) is optimal without requiring any phase or time shift. The appropriate time and phase shifts are determined iteratively and applied to the second set of (hplus, hcross) vectors. """ ############################################################################# # First copy over data into local memory, ensure lengths of time and # frequency domain vectors are consistent, and compute the maximized overlap # # 1) Cast into time-series h_plus1 = TimeSeries(hplus1, epoch=hplus1._epoch, delta_t=hplus1.delta_t, dtype=hplus1.dtype, copy=True) h_cross1 = TimeSeries(hcross1, epoch=hplus1._epoch, delta_t=hplus1.delta_t, dtype=hplus1.dtype, copy=True) h_plus2 = TimeSeries(hplus2, epoch=hplus2._epoch, delta_t=hplus2.delta_t, dtype=hplus2.dtype, copy=True) h_cross2 = TimeSeries(hcross2, epoch=hplus2._epoch, delta_t=hplus2.delta_t, dtype=hplus2.dtype, copy=True) # # 2) Ensure both input hplus vectors are equal in length if len(hplus2) > len(hplus1): h_plus1.append_zeros(len(hplus2) - len(hplus1)) h_cross1.append_zeros(len(hplus2) - len(hplus1)) elif len(hplus2) < len(hplus1): h_plus2.append_zeros(len(hplus1) - len(hplus2)) h_cross2.append_zeros(len(hplus1) - len(hplus2)) # # 3) Set the upper frequency cutoff to Nyquist if not set by User if high_frequency_cutoff == None: high_frequency_cutoff = 1. / h_plus1.delta_t / 2. # # 4) Compute LIGO noise psd if psd == None: raise IOError("Need compatible psd [or name] as input!") elif type(psd) == str: htilde = make_frequency_series(h_plus1) psd_name = psd psd = from_string(psd_name, len(htilde), htilde.delta_f, low_frequency_cutoff) ## # 5) Calculate Overlap (maximized) before alignment m = match(h_plus1, h_plus2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff) optimal_overlap = m[0] # FIXME if verbose: print(("Overlap BEFORE ALIGNMENT:", overlap_cplx(h_plus1, h_plus2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff, normalized=True))) print(("Match BEFORE ALIGNMENT:", m)) ############################################################################# # Iterate to obtain the correct phase and time shifts, using which we # align the two waveforms such that their unmaximized and maximized overlaps # agree. # # 1) Initialize phase/time offset counters t_shift_counter = 0 ph_shift_counter = 0 # # 2) Initialize initial garbage values to enter the while loop idx = 0 ph_shift = t_shift = 1e9 olap = 0 + 0j # # 3) Iteration begins # >>>>>> while np.abs(ph_shift) > phase_tolerance or \ np.abs(t_shift) > h_plus1.delta_t or \ np.abs(np.abs(olap.real) - optimal_overlap) > overlap_tolerance: if idx == 0: hp2, hc2 = h_plus2, h_cross2 # # 1) Determine the phase and time shifts for optimal match # by comparing hplus1/hcross1 with hp2/hc2 which is phase/time shifted # in previous iteration snr, corr, snr_norm = matched_filter_core(h_plus1, hp2, psd, low_frequency_cutoff, high_frequency_cutoff, None) max_snr, max_id = snr.abs_max_loc() if max_id != 0: t_shift = snr.delta_t * (len(snr) - max_id) else: t_shift = snr.delta_t * max_id ph_shift = np.angle(snr[max_id]) # # 2) Add them to running time/phase offset counter t_shift_counter += t_shift ph_shift_counter += ph_shift # if verbose: print((" >> Iteration %d\n" % (idx + 1))) print(("max_id = %d, id_shift = %d" % (max_id, int(t_shift / snr.delta_t)))) print(("t_shift = %f,\n ph_shift = %f" % (t_shift, ph_shift))) # #### # 3) Shift the second hp/hc pair (ORIGINAL) by cumulative phase/time offset hp2, hc2 = shift_waveform_phase_time(h_plus2, h_cross2, tsign * t_shift_counter, phsign * ph_shift_counter, verbose=verbose) # ### # 4) As time shifting can change array lengths, equalize again, compute psd ## if len(h_plus1) > len(hp2): hp2.append_zeros(len(h_plus1) - len(hp2)) htilde = make_frequency_series(h_plus1) psd = from_string(psd_name, len(htilde), htilde.delta_f, low_frequency_cutoff) elif len(h_plus1) < len(hp2): h_plus1.append_zeros(len(hp2) - len(h_plus1)) htilde = make_frequency_series(h_plus1) psd = from_string(psd_name, len(htilde), htilde.delta_f, low_frequency_cutoff) # # 5) Compute UNMAXIMIZED overlap. olap = overlap_cplx(h_plus1, hp2, psd=psd, low_frequency_cutoff=low_frequency_cutoff, high_frequency_cutoff=high_frequency_cutoff, normalized=True) if verbose: print(("Overlap AFTER ALIGNMENT = ", olap)) print(("Optimal Overlap = ", optimal_overlap)) # idx += 1 if verbose: print("\n") # >>>>>> # 3) Iteration ended. ############################################################################# # Verify the alignment ### if verify: # print("Verifying time alignment...") # # 1) Determine the phase and time shifts for optimal match snr, corr, snr_norm = matched_filter_core(h_plus1, hp2, psd, low_frequency_cutoff, high_frequency_cutoff, None) max_snr, max_id = snr.abs_max_loc() if verbose: print( ("Post-Alignment Index of MAX SNR (should be 0 or 1 or %d): %d" % (len(snr) - 1, max_id))) print(("Length of whole SNR time-series: ", len(snr))) # # 2) Test if current time shift is within tolerance if max_id != 0 and max_id != 1 and \ max_id != (len(snr)-1) and max_id != (len(snr)-2): raise RuntimeError("Warning: ALIGNMENT NOT CORRECT (see above)") else: print("Alignment in time correct..") # # 3) Test if current phase shift is within tolerance print("Verifying phase alignment...") ph_shift = np.angle(snr[max_id]) if np.abs(ph_shift) > phase_tolerance: if verbose: print(("dphi, dphi+pi, dphi-pi: ", ph_shift, ph_shift + np.pi, ph_shift - np.pi)) print( ("dphi/pi, dphi*pi: ", ph_shift / np.pi, ph_shift * np.pi)) raise RuntimeError( "Warning: Phasing alignment possibly incorrect.") else: if verbose: print(("Post-Alignmend Phase shift (should be < %.2e): %.2e" % (phase_tolerance, np.abs(ph_shift)))) print(("Alignment in phasing correct.. (within tol %.2e)" % phase_tolerance)) # ############################################################################# # TRIM the output arrays and return if trim_trailing: hp2 = trim_trailing_zeros(hp2) hc2 = trim_trailing_zeros(hc2) if trim_leading: hp2 = trim_leading_zeros(hp2) hc2 = trim_leading_zeros(hc2) # return hplus1, hcross1, hp2, hc2