Beispiel #1
0
def matched_filter_real_fd(template, psd):
    fdfilter = lal.CreateCOMPLEX16FrequencySeries(template.name, template.epoch,
        template.f0, template.deltaF, template.sampleUnits, len(template.data.data))
    fdfilter.data.data = template.data.data
    fdfilter = lal.WhitenCOMPLEX16FrequencySeries(fdfilter, psd)
    fdfilter.data.data /= np.sqrt(np.sum(np.abs(fdfilter.data.data)**2))
    fdfilter = lal.WhitenCOMPLEX16FrequencySeries(fdfilter, psd)
    return fdfilter
Beispiel #2
0
    def make_whitened_template(self, template_table_row):
        # FIXME: This is won't work
        #assert template_table_row in self.template_table, "The input Sngl_Inspiral:Table is not found in the workspace."

        # Create template
        fseries = generate_template(template_table_row,
                                    self.approximant,
                                    self.sample_rate_max,
                                    self.working_duration,
                                    self.f_low,
                                    self.fhigh,
                                    fwdplan=self.fwdplan,
                                    fworkspace=self.fworkspace)

        if FIR_WHITENER:
            #
            # Compute a product of freq series of the whitening kernel and the template (convolution in time domain) then add quadrature phase
            #
            assert (len(self.kernel_fseries.data.data) // 2 + 1) == len(
                fseries.data.data
            ), "the size of whitening kernel freq series does not match with a given format of COMPLEX16FrequencySeries."
            fseries.data.data *= self.kernel_fseries.data.data[
                len(self.kernel_fseries.data.data) // 2 - 1:]
            fseries = templates.QuadraturePhase.add_quadrature_phase(
                fseries, self.working_length)
        else:
            #
            # whiten and add quadrature phase ("sine" component)
            #

            if self.psd is not None:
                lal.WhitenCOMPLEX16FrequencySeries(fseries, self.psd)
                fseries = templates.QuadraturePhase.add_quadrature_phase(
                    fseries, self.working_length)

        #
        # compute time-domain autocorrelation function
        #

        if self.autocorrelation_length is not None:
            autocorrelation = templates.normalized_autocorrelation(
                fseries, self.revplan).data.data
        else:
            autocorrelation = None

        #
        # transform template to time domain
        #

        lal.COMPLEX16FreqTimeFFT(self.tseries, fseries, self.revplan)

        data = self.tseries.data.data
        epoch_time = fseries.epoch.gpsSeconds + fseries.epoch.gpsNanoSeconds * 1.e-9

        #
        # extract the portion to be used for filtering
        #

        #
        # condition the template if necessary (e.g. line up IMR
        # waveforms by peak amplitude)
        #

        if self.approximant in templates.gstlal_IMR_approximants:
            data, target_index = condition_imr_template(
                self.approximant, data, epoch_time, self.sample_rate_max,
                self.max_ringtime)
            # record the new end times for the waveforms (since we performed the shifts)
            template_table_row.end = LIGOTimeGPS(
                float(target_index - (len(data) - 1.)) / self.sample_rate_max)
        else:
            if self.sample_rate_max > self.fhigh * 2.:
                data, target_index = condition_ear_warn_template(
                    self.approximant, data, epoch_time, self.sample_rate_max,
                    self.max_shift_time)
                data *= tukeywindow(data, samps=32)
                # record the new end times for the waveforms (since we performed the shifts)
                template_table_row.end = LIGOTimeGPS(
                    float(target_index) / self.sample_rate_max)
            else:
                data *= tukeywindow(data, samps=32)

        data = data[-self.length_max:]

        #
        # normalize so that inner product of template with itself
        # is 2
        #

        norm = abs(numpy.dot(data, numpy.conj(data)))
        data *= cmath.sqrt(2 / norm)

        #
        # sigmasq = 2 \sum_{k=0}^{N-1} |\tilde{h}_{k}|^2 / S_{k} \Delta f
        #
        # XLALWhitenCOMPLEX16FrequencySeries() computed
        #
        # \tilde{h}'_{k} = \sqrt{2 \Delta f} \tilde{h}_{k} / \sqrt{S_{k}}
        #
        # and XLALCOMPLEX16FreqTimeFFT() computed
        #
        # h'_{j} = \Delta f \sum_{k=0}^{N-1} exp(2\pi i j k / N) \tilde{h}'_{k}
        #
        # therefore, "norm" is
        #
        # \sum_{j} |h'_{j}|^{2} = (\Delta f)^{2} \sum_{j} \sum_{k=0}^{N-1} \sum_{k'=0}^{N-1} exp(2\pi i j (k-k') / N) \tilde{h}'_{k} \tilde{h}'^{*}_{k'}
        #                       = (\Delta f)^{2} \sum_{k=0}^{N-1} \sum_{k'=0}^{N-1} \tilde{h}'_{k} \tilde{h}'^{*}_{k'} \sum_{j} exp(2\pi i j (k-k') / N)
        #                       = (\Delta f)^{2} N \sum_{k=0}^{N-1} |\tilde{h}'_{k}|^{2}
        #                       = (\Delta f)^{2} N 2 \Delta f \sum_{k=0}^{N-1} |\tilde{h}_{k}|^{2} / S_{k}
        #                       = (\Delta f)^{2} N sigmasq
        #
        # and \Delta f = 1 / (N \Delta t), so "norm" is
        #
        # \sum_{j} |h'_{j}|^{2} = 1 / (N \Delta t^2) sigmasq
        #
        # therefore
        #
        # sigmasq = norm * N * (\Delta t)^2
        #

        sigmasq = norm * len(data) / self.sample_rate_max**2.

        return data, autocorrelation, sigmasq