Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
conditioning_subroutines.py
Go to the documentation of this file.
1# Import required stuff
2import numpy as np
3from astropy import units as u
4from gwpy.timeseries import TimeSeries
5import warnings
6from scipy.signal import butter, sosfiltfilt
7
8# Routine to high-pass time series
9
10def high_pass_time_series(time_series, dt, fmin, attenuation, N):
11 """
12 High-pass a time series
13
14 Parameters
15 ----------
16 time_series : `TimeSeries`
17 GwPy TimeSeries object
18 dt : `float`
19 Sampling value of time series
20 fmin : `float`
21 Minimum frequency for high-pass
22 attenuation : `float`
23 Attenuation value at low-freq cut-off
24 N : `float`
25 Order of butterworth filter
26 """
27
28 # Following butterworth filters as applied to LAL:
29 # See : https://lscsoft.docs.ligo.org/lalsuite/lal/group___butterworth_time_series__c.html
30
31 # Number of samples
32 Ns = len(time_series)
33 fs = 1./dt # Sampling frequency
34 a1 = attenuation # Attenuation at the low-freq cut-off
35
36
37 w1 = np.tan(np.pi * fmin * dt) # Transformed frequency variable at f_min
38 wc = w1 * (1.0 / a1**0.5 - 1)**(1.0/(2.0*N)) # Cut-off freq. from attenuation
39 fc = fs * np.arctan(wc) / np.pi # For use in butterworth filter
40
41 # Construct the filter and then forward - backward filter the time-series
42 sos = butter(N, fc, btype='highpass', output='sos', fs=fs)
43 output = sosfiltfilt(sos, time_series)
44
45 output = TimeSeries(output, t0=time_series.epoch, dt=time_series.dt)
46 return output
47
48
49
50def time_array_condition_stage1(hp, hc, dt, t_extra, fmin):
51 """
52 Stage 1 of time-series conditioning - add taper and high-pass the time-series
53
54 Parameters
55 ----------
56 hp : `TimeSeries`
57 GwPy TimeSeries object
58 hc : `TimeSeries`
59 GwPy TimeSeries object
60 dt : `float`
61 Sampling value of time series
62 t_extra : `float`
63 Initial extra time for conditioning
64 fmin : `float`
65 Minimum frequency for high-pass
66 """
67
68 # Following XLALSimInspiralTDConditionStage1
69
70 # Generate the cos taper
71 Ntaper = np.round(t_extra/dt)
72 taper_array = np.arange(Ntaper)
73 w = 0.5 - 0.5*np.cos(taper_array*np.pi/Ntaper)
74 w_ones = np.ones(len(hp))
75 w_ones[:int(Ntaper)] *= w
76 hp *= w_ones
77 hc *= w_ones
78
79 # High pass filter the waveform.
80 hp = high_pass_time_series(hp, dt, fmin, 0.99, 8.)
81 hc = high_pass_time_series(hc, dt, fmin, 0.99, 8.)
82
83 # Remove trailing zeroes from array
84 np.trim_zeros(hp, trim='b')
85 np.trim_zeros(hc, trim='b')
86
87 return hp, hc
88
89
90def time_array_condition_stage2(hp, hc, dt, fmin, fmax):
91 """
92 Stage 2 of time-series conditioning - taper end of waveform based off maximum frequency
93
94 Parameters
95 ----------
96 hp : `TimeSeries`
97 GwPy TimeSeries object
98 hc : `TimeSeries`
99 GwPy TimeSeries object
100 dt : `float`
101 Sampling value of time series
102 fmin : `float`
103 Minimum frequency for high-pass
104 fmax : `float`
105 Minimum frequency for high-pass
106
107 """
108
109
110 # Following XLALSimInspiralTDConditionStage2
111 min_taper_samples = 4.
112 if len(hp)<2*min_taper_samples:
113 warnings.warn("Current waveform has less than %i samples: No Final tapering will be applied"%(2*min_taper_samples))
114 return 0
115
116 # taper end of waveform: 1 cycle at f_max; at least min_taper_samples
117 # note: this tapering is done so the waveform goes to zero at the next
118 # point beyond the end of the data
119 ntaper = int(np.round(1./(fmax*dt)))
120 ntaper = np.max([ntaper, min_taper_samples])
121
122 # Taper end of waveform
123 taper_array = np.arange(1, ntaper)
124 w = 0.5 - 0.5*np.cos(taper_array*np.pi/ntaper)
125 Nsize = len(hp)
126 w_ones = np.ones(Nsize)
127 w_ones[int(Nsize-ntaper+1):] *= w[::-1]
128 hp *= w_ones
129 hc *= w_ones
130
131
132 # Taper off one cycle at low frequency
133 ntaper = np.round(1./(fmin*dt))
134 ntaper = np.max([ntaper, min_taper_samples])
135
136 # Taper end of waveform
137 taper_array = np.arange(ntaper)
138 w = 0.5 - 0.5*np.cos(taper_array*np.pi/ntaper)
139 w_ones = np.ones(Nsize)
140 w_ones[:int(ntaper)] *= w
141 hp *= w_ones
142 hc *= w_ones
143
144 return hp, hc
145
146def resize_gwpy_timeseries(hp, start_id, new_length):
147 """
148 Resize a given gwpy TimeSeries which has a given length and starts at a point specified by start_id. If start_id
149 is negative, the timeseries will be padded on the left with that amount.
150
151 Parameters
152 ----------
153 hp : gwpy.TimeSeries
154 TimeSeries that needs to be resized
155
156 start_id : int
157 If positive, index at which TimeSeries will now start from. If negative, TimeSeries will be zero padded with
158 that length on the left.
159
160 new_length : int
161 Final length of output array. This will be done by clippling the end of the TimeSeries, if new_length is
162 larger than len(hp[start_id:]); otherwise zero_pad on right
163
164 Returns
165 -------
166 hp : gwpy.TimeSeries
167 Resized gwpy.TimeSeries object.
168
169 """
170 # Resize gwpy time series by prpending the array with zeros
171 # and then adjust the epoch accordingly
172 dt = hp.dt.value
173
174 # Do the left padding / cutting
175 if start_id < 0:
176 zeros = np.zeros(int(abs(start_id)))
177 hp = np.concatenate([zeros, hp])
178 elif start_id>=0:
179 hp = hp[int(start_id):]
180
181
182 # Right padding / cutting
183 end_id = int(len(hp) - new_length)
184 if end_id < 0 :
185 zeros = np.zeros(int(abs(end_id)))
186 hp = np.concatenate([hp, zeros])
187 elif end_id>0:
188 hp = hp[:-end_id]
189
190 fin_length = len(hp)
191 times_new = np.arange(0, new_length)*dt*u.s
192 times_new = times_new - times_new[np.argmax(hp)]
193 hp_out = hp
194 hp_out.times = times_new
195
196 return hp_out
def resize_gwpy_timeseries(hp, start_id, new_length)
Resize a given gwpy TimeSeries which has a given length and starts at a point specified by start_id.
def high_pass_time_series(time_series, dt, fmin, attenuation, N)
High-pass a time series.
def time_array_condition_stage1(hp, hc, dt, t_extra, fmin)
Stage 1 of time-series conditioning - add taper and high-pass the time-series.
def time_array_condition_stage2(hp, hc, dt, fmin, fmax)
Stage 2 of time-series conditioning - taper end of waveform based off maximum frequency.