Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALSimInspiralWaveformTaper.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 David McKechan, Thomas Cokelaer, Drew Keppel
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20
21#include <LALSimInspiral.h>
22#include <lal/LALError.h>
23#include <stdio.h>
24#include <math.h>
25
26/* hard-coded resampling filter length, see LALSimulation.c
27 * the filter is 19 samples long, resampling can produce ringing
28 * up to 9 samples away from an abrupt jump
29 */
31
32/**
33 * \addtogroup LALSimInspiralWaveformTaper_c
34 * \author McKechan D J A
35 *
36 * \brief The code \c XLALInspiralREAL4WaveformTaper() and
37 * \c XLALInspiralREAL8WaveTaper() impose a smooth time tapering at the
38 * beginning and/or the end of REAL4 or REAL8 waveforms in the time domain.
39 *
40 * They take either a \c REAL4Vector or a \c REAL8Vector and search for the
41 * beginning and end points of the signal, in case there are null data points
42 * at either end. They then taper the waveform from the ends to the second
43 * maxima from each end in the waveform, according to formula 3.35 of
44 * <tt>gr-qc/0001023</tt>.
45 *
46 * If the waveform does has less than 4 maxima, such that it cannot be tapered
47 * from the each end to the second peak then the waveform is tapered from the
48 * ends to the centre of the instead.
49 *
50 * The bookends option is an \c LALSimInspiralApplyTaper enumerator and allows the
51 * user to specify whether just the start, just the end or both the start and
52 * end of the signal are tapered. These options are #LAL_SIM_INSPIRAL_TAPER_START,
53 * #LAL_SIM_INSPIRAL_TAPER_END and #LAL_SIM_INSPIRAL_TAPER_STARTEND.
54 *
55 * ### Prototypes ###
56 *
57 * <tt>XLALInspiralREAL4WaveformTaper()</tt>
58 * <tt>XLALInspiralREAL8WaveformTaper()</tt>
59 *
60 * ### Description ###
61 *
62 *
63 * ### Uses ###
64 *
65 *
66 * ### Notes ###
67 *
68 * \{
69 */
70
72 REAL4Vector *signalvec, /**< pointer to waveform vector */
73 LALSimInspiralApplyTaper bookends /**< taper type enumerator */
74 )
75{
76 UINT4 i, start=0, end=0, mid, n=0; /* indices */
77 UINT4 flag, safe = 1;
78 UINT4 length;
79 REAL4 z, sigma;
80 REAL4 realN, realI; /* REAL4 values of n & i used for the calculations */
81
82 if ( !signalvec )
84
85 if ( !signalvec->data )
87
88 /* Check we have chosen a valid tapering method */
89 if ( (UINT4) bookends >= (UINT4) LAL_SIM_INSPIRAL_TAPER_NUM_OPTS )
91
92 length = signalvec->length;
93
94 if( bookends == LAL_SIM_INSPIRAL_TAPER_NONE )
95 {
96 XLALPrintWarning( "No taper specified; not tapering.\n" );
97 return XLAL_SUCCESS;
98 }
99
100 /* Search for start and end of signal */
101 flag = 0;
102 i = 0;
103 while( flag == 0 && i < length )
104 {
105 if( signalvec->data[i] != 0. )
106 {
107 start = i;
108 flag = 1;
109 }
110 i++;
111 }
112 if ( flag == 0 )
113 {
114 XLALPrintWarning( "No signal found in the vector. Cannot taper.\n" );
115 return XLAL_SUCCESS;
116 }
117
118 flag = 0;
119 i = length - 1;
120 while( flag == 0 )
121 {
122 if( signalvec->data[i] != 0. )
123 {
124 end = i;
125 flag = 1;
126 }
127 i--;
128 }
129
130 /* Check we have more than 2 data points */
131 if( (end - start) <= 1 )
132 {
133 XLALPrintWarning( "Data less than 3 points, cannot taper!\n" );
134 safe = 0;
135 }
136
137 if( safe == 1 )
138 {
139 /* Calculate middle point in case of short waveform */
140 mid = (start+end)/2;
141
142 /* If requested search for second peak from start and taper */
143 if( bookends != LAL_SIM_INSPIRAL_TAPER_END )
144 {
145 flag = 0;
146 i = start+1;
147 while( flag < 2 && i != mid )
148 {
149 if( fabs(signalvec->data[i]) >= fabs(signalvec->data[i-1]) &&
150 fabs(signalvec->data[i]) >= fabs(signalvec->data[i+1]) )
151 {
152 if( fabs(signalvec->data[i]) == fabs(signalvec->data[i+1]) )
153 i++;
154 /* only count local extrema more than 19 samples in */
155 if ( i-start > LALSIMULATION_RINGING_EXTENT )
156 flag++;
157 n = i - start;
158 }
159 i++;
160 }
161
162 /* Have we reached the middle without finding 2 peaks? */
163 if( flag < 2 )
164 n = mid - start;
165
166 /* Taper to that point */
167 realN = (REAL4)(n);
168 signalvec->data[start] = 0.0;
169 for(i=start+1; i < start + n - 1; i++)
170 {
171 realI = (REAL4)(i - start);
172 z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN - 1.0));
173 sigma = 1.0/(exp(z) + 1.0);
174 signalvec->data[i] = signalvec->data[i]*sigma;
175 }
176 }
177
178 /* If requested search for second peak from end */
179 if( bookends == LAL_SIM_INSPIRAL_TAPER_END || bookends == LAL_SIM_INSPIRAL_TAPER_STARTEND )
180 {
181 i = end - 1;
182 flag = 0;
183 while( flag < 2 && i != mid )
184 {
185 if( fabs(signalvec->data[i]) >= fabs(signalvec->data[i+1]) &&
186 fabs(signalvec->data[i]) >= fabs(signalvec->data[i-1]) )
187 {
188 if( fabs(signalvec->data[i]) == fabs(signalvec->data[i-1]) )
189 i--;
190 /* only count local extrema more than 19 samples in */
192 flag++;
193 n = end - i;
194 }
195 i--;
196 }
197
198 /* Have we reached the middle without finding 2 peaks? */
199 if( flag < 2 )
200 {
201 n = end - mid;
202 }
203
204 /* Taper to that point */
205 realN = (REAL4)(n);
206 signalvec->data[end] = 0.0;
207 for(i=end-1; i > end-n+1; i--)
208 {
209 realI = (REAL4)(end - i);
210 z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN-1.0));
211 sigma = 1.0/(exp(z) + 1.0);
212 signalvec->data[i] = signalvec->data[i]*sigma;
213 }
214 }
215 }
216
217 return XLAL_SUCCESS;
218}
219
221 REAL8Vector *signalvec, /**< pointer to waveform vector */
222 LALSimInspiralApplyTaper bookends /**< taper type enumerator */
223 )
224{
225 UINT4 i, start=0, end=0, mid, n=0; /* indices */
226 UINT4 flag, safe = 1;
227 UINT4 length;
228 REAL8 z, sigma;
229 REAL8 realN, realI; /* REAL4 values of n & i used for the calculations */
230
231 if ( !signalvec )
233
234 if ( !signalvec->data )
236
237 /* Check we have chosen a valid tapering method */
238 if ( (UINT4) bookends >= (UINT4) LAL_SIM_INSPIRAL_TAPER_NUM_OPTS )
240
241 length = signalvec->length;
242
243 if( bookends == LAL_SIM_INSPIRAL_TAPER_NONE )
244 {
245 XLALPrintWarning( "No taper specified; not tapering.\n" );
246 return XLAL_SUCCESS;
247 }
248
249 /* Search for start and end of signal */
250 flag = 0;
251 i = 0;
252 while( flag == 0 && i < length )
253 {
254 if( signalvec->data[i] != 0. )
255 {
256 start = i;
257 flag = 1;
258 }
259 i++;
260 }
261 if ( flag == 0 )
262 {
263 XLALPrintWarning( "No signal found in the vector. Cannot taper.\n" );
264 return XLAL_SUCCESS;
265 }
266
267 flag = 0;
268 i = length - 1;
269 while( flag == 0 )
270 {
271 if( signalvec->data[i] != 0. )
272 {
273 end = i;
274 flag = 1;
275 }
276 i--;
277 }
278
279 /* Check we have more than 2 data points */
280 if( (end - start) <= 1 )
281 {
282 XLALPrintWarning( "Data less than 3 points, cannot taper!\n" );
283 safe = 0;
284 }
285
286 if( safe == 1 )
287 {
288 /* Calculate middle point in case of short waveform */
289 mid = (start+end)/2;
290
291 /* If requested search for second peak from start and taper */
292 if( bookends != LAL_SIM_INSPIRAL_TAPER_END )
293 {
294 flag = 0;
295 i = start+1;
296 while( flag < 2 && i != mid )
297 {
298 if( fabs(signalvec->data[i]) >= fabs(signalvec->data[i-1]) &&
299 fabs(signalvec->data[i]) >= fabs(signalvec->data[i+1]) )
300 {
301 if( fabs(signalvec->data[i]) == fabs(signalvec->data[i+1]) )
302 i++;
303 /* only count local extrema more than 19 samples in */
304 if ( i-start > LALSIMULATION_RINGING_EXTENT )
305 flag++;
306 n = i - start;
307 }
308 i++;
309 }
310
311 /* Have we reached the middle without finding 2 peaks? */
312 if( flag < 2 )
313 n = mid - start;
314
315 /* Taper to that point */
316 realN = (REAL8)(n);
317 signalvec->data[start] = 0.0;
318 for(i=start+1; i < start + n - 1; i++)
319 {
320 realI = (REAL8)(i - start);
321 z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN - 1.0));
322 sigma = 1.0/(exp(z) + 1.0);
323 signalvec->data[i] = signalvec->data[i]*sigma;
324 }
325 }
326
327 /* If requested search for second peak from end */
328 if( bookends == LAL_SIM_INSPIRAL_TAPER_END || bookends == LAL_SIM_INSPIRAL_TAPER_STARTEND )
329 {
330 i = end - 1;
331 flag = 0;
332 while( flag < 2 && i != mid )
333 {
334 if( fabs(signalvec->data[i]) >= fabs(signalvec->data[i+1]) &&
335 fabs(signalvec->data[i]) >= fabs(signalvec->data[i-1]) )
336 {
337 if( fabs(signalvec->data[i]) == fabs(signalvec->data[i-1]) )
338 i--;
339 /* only count local extrema more than 19 samples in */
341 flag++;
342 n = end - i;
343 }
344 i--;
345 }
346
347 /* Have we reached the middle without finding 2 peaks? */
348 if( flag < 2 )
349 {
350 n = end - mid;
351 }
352
353 /* Taper to that point */
354 realN = (REAL8)(n);
355 signalvec->data[end] = 0.0;
356 for(i=end-1; i > end-n+1; i--)
357 {
358 realI = (REAL8)(end - i);
359 z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN-1.0));
360 sigma = 1.0/(exp(z) + 1.0);
361 signalvec->data[i] = signalvec->data[i]*sigma;
362 }
363 }
364 }
365
366 return XLAL_SUCCESS;
367}
368
369/** \} */
static double sigma(const double a, const double b, const sysq *system)
Internal function that computes the spin-spin couplings.
const UINT4 LALSIMULATION_RINGING_EXTENT
double i
Definition: bh_ringdown.c:118
double REAL8
uint32_t UINT4
float REAL4
LALSimInspiralApplyTaper
Enumeration to specify the tapering method to apply to the waveform.
@ LAL_SIM_INSPIRAL_TAPER_STARTEND
Taper the start and the end of the waveform.
@ LAL_SIM_INSPIRAL_TAPER_NUM_OPTS
Number of elements in enum, useful for checking bounds.
@ LAL_SIM_INSPIRAL_TAPER_END
Taper the end of the waveform.
@ LAL_SIM_INSPIRAL_TAPER_NONE
No tapering.
int XLALSimInspiralREAL8WaveTaper(REAL8Vector *signalvec, LALSimInspiralApplyTaper bookends)
int XLALSimInspiralREAL4WaveTaper(REAL4Vector *signalvec, LALSimInspiralApplyTaper bookends)
#define XLAL_ERROR(...)
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EINVAL
end
REAL4 * data
REAL8 * data