def full_matched_filter_and_cluster(self, template, template_norm, stilde, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- htilde : FrequencySeries The template waveform. Must come from the FilterBank class. template_norm : float The htilde, template normalization factor. stilde : FrequencySeries The strain data to be filtered. window : int The size of the cluster window in samples. Returns ------- snr : TimeSeries A time series containing the complex snr. norm : float The normalization of the complex snr. corrrelation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ snr, corr, norm = matched_filter_core(template, stilde, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, h_norm=template_norm, out=self.snr_mem, corr_out=self.corr_mem) idx, snrv = events.threshold(snr[stilde.analyze], self.snr_threshold / norm) if len(idx) == 0: return [], [], [], [], [] logging.info("%s points above threshold" % str(len(idx))) idx, snrv = events.cluster_reduce(idx, snrv, window) logging.info("%s clustered points" % str(len(idx))) return snr, norm, corr, idx, snrv
def full_matched_filter_and_cluster_fc(self, segnum, template_norm, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- segnum : int Index into the list of segments at MatchedFilterControl construction against which to filter. template_norm : float The htilde, template normalization factor. window : int Size of the window over which to cluster triggers, in samples Returns ------- snr : TimeSeries A time series containing the complex snr. norm : float The normalization of the complex snr. corrrelation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ norm = (4.0 * self.delta_f) / sqrt(template_norm) self.correlators[segnum].correlate() self.ifft.execute() idx, snrv = events.threshold( self.snr_mem[self.segments[segnum].analyze], self.snr_threshold / norm) idx, snrv = events.cluster_reduce(idx, snrv, window) if len(idx) == 0: return [], [], [], [], [] logging.info("%s points above threshold" % str(len(idx))) return self.snr_mem, norm, self.corr_mem, idx, snrv
def full_matched_filter_and_cluster_fc(self, segnum, template_norm, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- segnum : int Index into the list of segments at MatchedFilterControl construction against which to filter. template_norm : float The htilde, template normalization factor. window : int Size of the window over which to cluster triggers, in samples Returns ------- snr : TimeSeries A time series containing the complex snr. norm : float The normalization of the complex snr. corrrelation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ norm = (4.0 * self.delta_f) / sqrt(template_norm) self.correlators[segnum].correlate() self.ifft.execute() idx, snrv = events.threshold(self.snr_mem[self.segments[segnum].analyze], self.snr_threshold / norm) idx, snrv = events.cluster_reduce(idx, snrv, window) if len(idx) == 0: return [], [], [], [], [] logging.info("%s points above threshold" % str(len(idx))) return self.snr_mem, norm, self.corr_mem, idx, snrv
def heirarchical_matched_filter_and_cluster(self, htilde, template_norm, stilde, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- htilde : FrequencySeries The template waveform. Must come from the FilterBank class. template_norm : float The htilde, template normalization factor. stilde : FrequencySeries The strain data to be filtered. window : int The size of the cluster window in samples. Returns ------- snr : TimeSeries A time series containing the complex snr at the reduced sample rate. norm : float The normalization of the complex snr. corrrelation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ from pycbc.fft.fftw_pruned import pruned_c2cifft, fft_transpose norm = (4.0 * stilde.delta_f) / sqrt(template_norm) correlate(htilde[self.kmin_red:self.kmax_red], stilde[self.kmin_red:self.kmax_red], self.corr_mem[self.kmin_red:self.kmax_red]) ifft(self.corr_mem, self.snr_mem) if not hasattr(stilde, 'red_analyze'): stilde.red_analyze = \ slice(stilde.analyze.start/self.downsample_factor, stilde.analyze.stop/self.downsample_factor) idx_red, snrv_red = events.threshold( self.snr_mem[stilde.red_analyze], self.snr_threshold / norm * self.upsample_threshold) if len(idx_red) == 0: return [], None, [], [], [] idx_red, _ = events.cluster_reduce(idx_red, snrv_red, window / self.downsample_factor) logging.info("%s points above threshold at reduced resolution"\ %(str(len(idx_red)),)) # The fancy upsampling is here if self.upsample_method == 'pruned_fft': idx = (idx_red + stilde.analyze.start/self.downsample_factor)\ * self.downsample_factor idx = smear(idx, self.downsample_factor) # cache transposed versions of htilde and stilde if not hasattr(self.corr_mem_full, 'transposed'): self.corr_mem_full.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) if not hasattr(htilde, 'transposed'): htilde.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) htilde.transposed[self.kmin_full:self.kmax_full] = htilde[ self.kmin_full:self.kmax_full] htilde.transposed = fft_transpose(htilde.transposed) if not hasattr(stilde, 'transposed'): stilde.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) stilde.transposed[self.kmin_full:self.kmax_full] = stilde[ self.kmin_full:self.kmax_full] stilde.transposed = fft_transpose(stilde.transposed) correlate(htilde.transposed, stilde.transposed, self.corr_mem_full.transposed) snrv = pruned_c2cifft(self.corr_mem_full.transposed, self.inter_vec, idx, pretransposed=True) idx = idx - stilde.analyze.start idx2, snrv = events.threshold(Array(snrv, copy=False), self.snr_threshold / norm) if len(idx2) > 0: correlate(htilde[self.kmax_red:self.kmax_full], stilde[self.kmax_red:self.kmax_full], self.corr_mem_full[self.kmax_red:self.kmax_full]) idx, snrv = events.cluster_reduce(idx[idx2], snrv, window) else: idx, snrv = [], [] logging.info("%s points at full rate and clustering" % len(idx)) return self.snr_mem, norm, self.corr_mem_full, idx, snrv else: raise ValueError("Invalid upsample method")
def full_matched_filter_and_cluster(self, hplus, hcross, hplus_norm, hcross_norm, psd, stilde, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- h_quantities : Various FILL ME IN stilde : FrequencySeries The strain data to be filtered. window : int The size of the cluster window in samples. Returns ------- snr : TimeSeries A time series containing the complex snr. norm : float The normalization of the complex snr. correlation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ I_plus, Iplus_corr, Iplus_norm = matched_filter_core( hplus, stilde, h_norm=hplus_norm, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, out=self.snr_plus_mem, corr_out=self.corr_plus_mem) I_cross, Icross_corr, Icross_norm = matched_filter_core( hcross, stilde, h_norm=hcross_norm, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, out=self.snr_cross_mem, corr_out=self.corr_cross_mem) # The information on the complex side of this overlap is important # we may want to use this in the future. if not id(hplus) == self.cached_hplus_hcross_hplus: self.cached_hplus_hcross_correlation = None if not id(hcross) == self.cached_hplus_hcross_hcross: self.cached_hplus_hcross_correlation = None if not id(psd) == self.cached_hplus_hcross_psd: self.cached_hplus_hcross_correlation = None if self.cached_hplus_hcross_correlation is None: hplus_cross_corr = overlap_cplx(hplus, hcross, psd=psd, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, normalized=False) hplus_cross_corr = numpy.real(hplus_cross_corr) hplus_cross_corr = hplus_cross_corr / (hcross_norm * hplus_norm)**0.5 self.cached_hplus_hcross_correlation = hplus_cross_corr self.cached_hplus_hcross_hplus = id(hplus) self.cached_hplus_hcross_hcross = id(hcross) self.cached_hplus_hcross_psd = id(psd) else: hplus_cross_corr = self.cached_hplus_hcross_correlation snr = compute_max_snr_over_sky_loc_stat(I_plus, I_cross, hplus_cross_corr, thresh=self.snr_threshold, out=self.snr_mem, hpnorm=Iplus_norm, hcnorm=Icross_norm, analyse_slice=stilde.analyze) # FIXME: This should live further down # Convert output to pycbc TimeSeries delta_t = 1.0 / (self.tlen * stilde.delta_f) snr = TimeSeries(snr, epoch=stilde._epoch, delta_t=delta_t, copy=False) idx, snrv = events.threshold_real_numpy(snr[stilde.analyze], self.snr_threshold) if len(idx) == 0: return [], 0, 0, [], [], [], [], 0, 0, 0 logging.info("%s points above threshold" % str(len(idx))) idx, snrv = events.cluster_reduce(idx, snrv, window) logging.info("%s clustered points" % str(len(idx))) u_vals, coa_phase = compute_u_val_for_sky_loc_stat( I_plus.data, I_cross.data, hplus_cross_corr, indices=idx + stilde.analyze.start, hpnorm=Iplus_norm, hcnorm=Icross_norm) return snr, Iplus_corr, Icross_corr, idx, snrv, u_vals, coa_phase,\ hplus_cross_corr, Iplus_norm, Icross_norm
def full_matched_filter_and_cluster(self, hplus, hcross, hplus_norm, hcross_norm, psd, stilde, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- h_quantities : Various FILL ME IN stilde : FrequencySeries The strain data to be filtered. window : int The size of the cluster window in samples. Returns ------- snr : TimeSeries A time series containing the complex snr. norm : float The normalization of the complex snr. correlation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ I_plus, Iplus_corr, Iplus_norm = matched_filter_core(hplus, stilde, h_norm=hplus_norm, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, out=self.snr_plus_mem, corr_out=self.corr_plus_mem) I_cross, Icross_corr, Icross_norm = matched_filter_core(hcross, stilde, h_norm=hcross_norm, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, out=self.snr_cross_mem, corr_out=self.corr_cross_mem) # The information on the complex side of this overlap is important # we may want to use this in the future. if not id(hplus) == self.cached_hplus_hcross_hplus: self.cached_hplus_hcross_correlation = None if not id(hcross) == self.cached_hplus_hcross_hcross: self.cached_hplus_hcross_correlation = None if not id(psd) == self.cached_hplus_hcross_psd: self.cached_hplus_hcross_correlation = None if self.cached_hplus_hcross_correlation is None: hplus_cross_corr = overlap_cplx(hplus, hcross, psd=psd, low_frequency_cutoff=self.flow, high_frequency_cutoff=self.fhigh, normalized=False) hplus_cross_corr = numpy.real(hplus_cross_corr) hplus_cross_corr = hplus_cross_corr / (hcross_norm*hplus_norm)**0.5 self.cached_hplus_hcross_correlation = hplus_cross_corr self.cached_hplus_hcross_hplus = id(hplus) self.cached_hplus_hcross_hcross = id(hcross) self.cached_hplus_hcross_psd = id(psd) else: hplus_cross_corr = self.cached_hplus_hcross_correlation snr = compute_max_snr_over_sky_loc_stat(I_plus,I_cross, hplus_cross_corr, thresh=self.snr_threshold, out=self.snr_mem, hpnorm=Iplus_norm, hcnorm=Icross_norm, analyse_slice=stilde.analyze) # FIXME: This should live further down # Convert output to pycbc TimeSeries delta_t = 1.0 / (self.tlen * stilde.delta_f) snr = TimeSeries(snr, epoch=stilde._epoch, delta_t=delta_t, copy=False) idx, snrv = events.threshold_real_numpy(snr[stilde.analyze], self.snr_threshold) if len(idx) == 0: return [], 0, 0, [], [], [], [], 0, 0, 0 logging.info("%s points above threshold" % str(len(idx))) idx, snrv = events.cluster_reduce(idx, snrv, window) logging.info("%s clustered points" % str(len(idx))) u_vals, coa_phase = compute_u_val_for_sky_loc_stat( I_plus.data, I_cross.data, hplus_cross_corr, indices=idx+stilde.analyze.start, hpnorm=Iplus_norm, hcnorm=Icross_norm) return snr, Iplus_corr, Icross_corr, idx, snrv, u_vals, coa_phase,\ hplus_cross_corr, Iplus_norm, Icross_norm
def heirarchical_matched_filter_and_cluster(self, segnum, template_norm, window): """ Return the complex snr and normalization. Calculated the matched filter, threshold, and cluster. Parameters ---------- segnum : int Index into the list of segments at MatchedFilterControl construction template_norm : float The htilde, template normalization factor. window : int Size of the window over which to cluster triggers, in samples Returns ------- snr : TimeSeries A time series containing the complex snr at the reduced sample rate. norm : float The normalization of the complex snr. corrrelation: FrequencySeries A frequency series containing the correlation vector. idx : Array List of indices of the triggers. snrv : Array The snr values at the trigger locations. """ from pycbc.fft.fftw_pruned import pruned_c2cifft, fft_transpose htilde = self.htilde stilde = self.segments[segnum] norm = (4.0 * stilde.delta_f) / sqrt(template_norm) correlate(htilde[self.kmin_red:self.kmax_red], stilde[self.kmin_red:self.kmax_red], self.corr_mem[self.kmin_red:self.kmax_red]) ifft(self.corr_mem, self.snr_mem) if not hasattr(stilde, 'red_analyze'): stilde.red_analyze = \ slice(stilde.analyze.start/self.downsample_factor, stilde.analyze.stop/self.downsample_factor) idx_red, snrv_red = events.threshold(self.snr_mem[stilde.red_analyze], self.snr_threshold / norm * self.upsample_threshold) if len(idx_red) == 0: return [], None, [], [], [] idx_red, _ = events.cluster_reduce(idx_red, snrv_red, window / self.downsample_factor) logging.info("%s points above threshold at reduced resolution"\ %(str(len(idx_red)),)) # The fancy upsampling is here if self.upsample_method=='pruned_fft': idx = (idx_red + stilde.analyze.start/self.downsample_factor)\ * self.downsample_factor idx = smear(idx, self.downsample_factor) # cache transposed versions of htilde and stilde if not hasattr(self.corr_mem_full, 'transposed'): self.corr_mem_full.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) if not hasattr(htilde, 'transposed'): htilde.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) htilde.transposed[self.kmin_full:self.kmax_full] = htilde[self.kmin_full:self.kmax_full] htilde.transposed = fft_transpose(htilde.transposed) if not hasattr(stilde, 'transposed'): stilde.transposed = zeros(len(self.corr_mem_full), dtype=self.dtype) stilde.transposed[self.kmin_full:self.kmax_full] = stilde[self.kmin_full:self.kmax_full] stilde.transposed = fft_transpose(stilde.transposed) correlate(htilde.transposed, stilde.transposed, self.corr_mem_full.transposed) snrv = pruned_c2cifft(self.corr_mem_full.transposed, self.inter_vec, idx, pretransposed=True) idx = idx - stilde.analyze.start idx2, snrv = events.threshold(Array(snrv, copy=False), self.snr_threshold / norm) if len(idx2) > 0: correlate(htilde[self.kmax_red:self.kmax_full], stilde[self.kmax_red:self.kmax_full], self.corr_mem_full[self.kmax_red:self.kmax_full]) idx, snrv = events.cluster_reduce(idx[idx2], snrv, window) else: idx, snrv = [], [] logging.info("%s points at full rate and clustering" % len(idx)) return self.snr_mem, norm, self.corr_mem_full, idx, snrv else: raise ValueError("Invalid upsample method")