gstlal  0.8.1
 All Classes Namespaces Files Functions Variables Pages
coherent_null.py
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 # Preamble
21 #
22 # =============================================================================
23 #
24 
25 import scipy.fftpack
26 import numpy
27 import math
28 
29 import lal
30 from pylal.xlal.datatypes.real8frequencyseries import REAL8FrequencySeries
31 
32 #
33 # =============================================================================
34 #
35 # Functions
36 #
37 # =============================================================================
38 #
39 
40 def factors_to_fir_kernel(coh_facs):
41  """
42  Compute a finite impulse-response filter kernel from a power
43  spectral density conforming to the LAL normalization convention,
44  such that if zero-mean unit-variance Gaussian random noise is fed
45  into an FIR filter using the kernel the filter's output will
46  possess the given PSD. The PSD must be provided as a
47  REAL8FrequencySeries object (see
48  pylal.xlal.datatypes.real8frequencyseries).
49 
50  The return value is the tuple (kernel, latency, sample rate). The
51  kernel is a numpy array containing the filter kernel, the latency
52  is the filter latency in samples and the sample rate is in Hz.
53  """
54  #
55  # this could be relaxed with some work
56  #
57 
58  assert coh_facs.f0 == 0.0
59 
60  #
61  # extract the PSD bins and determine sample rate for kernel
62  #
63 
64  data = coh_facs.data
65  sample_rate = 2 * int(round(coh_facs.f0 + len(data) * coh_facs.deltaF))
66 
67  #
68  # compute the FIR kernel. it always has an odd number of samples
69  # and no DC offset.
70  #
71 
72  data[0] = data[-1] = 0.0
73  tmp = numpy.zeros((2 * len(data) - 1,), dtype = data.dtype)
74  tmp[0] = data[0]
75  tmp[1::2] = data[1:]
76  data = tmp
77  del tmp
78  kernel = scipy.fftpack.irfft(data)
79  kernel = numpy.roll(kernel, (len(kernel) - 1) / 2)
80 
81  #
82  # apply a Tukey window whose flat bit is 50% of the kernel.
83  # preserve the FIR kernel's square magnitude
84  #
85 
86  norm_before = numpy.dot(kernel, kernel)
87  kernel *= lal.CreateTukeyREAL8Window(len(kernel), .5).data.data
88  kernel *= math.sqrt(norm_before / numpy.dot(kernel, kernel))
89 
90  #
91  # the kernel's latency
92  #
93 
94  latency = (len(kernel) + 1) / 2 - 1
95 
96  #
97  # done
98  #
99 
100  return kernel, latency, sample_rate
101 
102 def psd_to_impulse_response(PSD1, PSD2):
103 
104  assert PSD1.f0 == PSD2.f0
105  assert PSD1.deltaF == PSD2.deltaF
106  assert len(PSD1.data) == len(PSD2.data)
107 
108  coh_facs_H1 = REAL8FrequencySeries()
109  coh_facs_H1.f0 = PSD1.f0
110  coh_facs_H1.deltaF = PSD1.deltaF
111  coh_facs_H1.data = PSD2.data/(PSD1.data + PSD2.data)
112  # work around referencing vs. copying structure
113  data = coh_facs_H1.data
114  data[0] = data[-1] = 0.0
115  coh_facs_H1.data = data
116 
117  coh_facs_H2 = REAL8FrequencySeries()
118  coh_facs_H2.f0 = PSD2.f0
119  coh_facs_H2.deltaF = PSD2.deltaF
120  coh_facs_H2.data = PSD1.data/(PSD1.data + PSD2.data)
121  # work around referencing vs. copying structure
122  data = coh_facs_H2.data
123  data[0] = data[-1] = 0.0
124  coh_facs_H2.data = data
125 
126  #
127  # set up fir filter
128  #
129 
130  H1_impulse, H1_latency, H1_srate = factors_to_fir_kernel(coh_facs_H1)
131  H2_impulse, H2_latency, H2_srate = factors_to_fir_kernel(coh_facs_H2)
132 
133  assert H1_srate == H2_srate
134 
135  return H1_impulse, H1_latency, H2_impulse, H2_latency, H1_srate