gstlal  1.4.1
coherent_null.py
Go to the documentation of this file.
1 # Copyright (C) 2012 Madeline Wade
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License as published by the
5 # Free Software Foundation; either version 2 of the License, or (at your
6 # option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 # Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 
17 
18 
19 
20 
21 #
22 # =============================================================================
23 #
24 # Preamble
25 #
26 # =============================================================================
27 #
28 
29 import scipy.fftpack
30 import numpy
31 import math
32 
33 import lal
34 
35 #
36 # =============================================================================
37 #
38 # Functions
39 #
40 # =============================================================================
41 #
42 
43 def factors_to_fir_kernel(coh_facs):
44  """
45  Compute a finite impulse-response filter kernel from a power
46  spectral density conforming to the LAL normalization convention,
47  such that if zero-mean unit-variance Gaussian random noise is fed
48  into an FIR filter using the kernel the filter's output will
49  possess the given PSD. The PSD must be provided as a
50  REAL8FrequencySeries object (see lal's swig binding documentation).
51 
52  The return value is the tuple (kernel, latency, sample rate). The
53  kernel is a numpy array containing the filter kernel, the latency
54  is the filter latency in samples and the sample rate is in Hz.
55  """
56  #
57  # this could be relaxed with some work
58  #
59 
60  assert coh_facs.f0 == 0.0
61 
62  #
63  # extract the PSD bins and determine sample rate for kernel
64  #
65 
66  data = coh_facs.data.data
67  sample_rate = 2 * int(round(coh_facs.f0 + len(data) * coh_facs.deltaF))
68 
69  #
70  # compute the FIR kernel. it always has an odd number of samples
71  # and no DC offset.
72  #
73 
74  data[0] = data[-1] = 0.0
75  tmp = numpy.zeros((2 * len(data) - 1,), dtype = data.dtype)
76  tmp[0] = data[0]
77  tmp[1::2] = data[1:]
78  data = tmp
79  del tmp
80  kernel = scipy.fftpack.irfft(data)
81  kernel = numpy.roll(kernel, (len(kernel) - 1) / 2)
82 
83  #
84  # apply a Tukey window whose flat bit is 50% of the kernel.
85  # preserve the FIR kernel's square magnitude
86  #
87 
88  norm_before = numpy.dot(kernel, kernel)
89  kernel *= lal.CreateTukeyREAL8Window(len(kernel), .5).data.data
90  kernel *= math.sqrt(norm_before / numpy.dot(kernel, kernel))
91 
92  #
93  # the kernel's latency
94  #
95 
96  latency = (len(kernel) + 1) / 2 - 1
97 
98  #
99  # done
100  #
101 
102  return kernel, latency, sample_rate
103 
104 def psd_to_impulse_response(PSD1, PSD2):
105 
106  assert PSD1.f0 == PSD2.f0
107  assert PSD1.deltaF == PSD2.deltaF
108  assert len(PSD1.data.data) == len(PSD2.data.data)
109 
110  coh_facs_H1 = lal.CreateREAL8FrequencySeries(
111  name = "",
112  epoch = PSD1.epoch,
113  f0 = PSD1.f0,
114  deltaF = PSD1.deltaF,
115  sampleUnits = lal.DimensionlessUnit,
116  length = len(PSD1.data.data)
117  )
118  coh_facs_H1.data.data = PSD2.data.data / (PSD1.data.data + PSD2.data.data)
119  coh_facs_H1.data.data[0] = coh_facs_H1.data.data[-1] = 0.0
120 
121  coh_facs_H2 = lal.REAL8FrequencySeries(
122  name = "",
123  epoch = PSD2.epoch,
124  f0 = PSD2.f0,
125  deltaF = PSD2.deltaF,
126  sampleUnits = lal.DimensionlessUnit,
127  length = len(PSD2.data.data)
128  )
129  coh_facs_H2.data = PSD1.data.data / (PSD1.data.data + PSD2.data.data)
130  coh_facs_H2.data[0] = coh_facs_H2.data[-1] = 0.0
131 
132  #
133  # set up fir filter
134  #
135 
136  H1_impulse, H1_latency, H1_srate = factors_to_fir_kernel(coh_facs_H1)
137  H2_impulse, H2_latency, H2_srate = factors_to_fir_kernel(coh_facs_H2)
138 
139  assert H1_srate == H2_srate
140 
141  return H1_impulse, H1_latency, H2_impulse, H2_latency, H1_srate