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
LALSimBurst.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007--2015 J. Creighton, K. Cannon, K. Wette, R. Prix, A. Mercer
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 */
19
20
21/*
22 * ============================================================================
23 *
24 * Preamble
25 *
26 * ============================================================================
27 */
28
29
30#include <math.h>
31#include <gsl/gsl_rng.h>
32#include <gsl/gsl_randist.h>
33#include <lal/LALConstants.h>
34#include <lal/LALDatatypes.h>
35#include <lal/LALError.h>
36#include <lal/LALSimBurst.h>
37#include <lal/FrequencySeries.h>
38#include <lal/Sequence.h>
39#include <lal/TimeFreqFFT.h>
40#include <lal/TimeSeries.h>
41#include <lal/RealFFT.h>
42#include <lal/Units.h>
43#include <lal/Date.h>
44#include "check_series_macros.h"
45
46
47/*
48 * ============================================================================
49 *
50 * Static Functions
51 *
52 * ============================================================================
53 */
54
55
56/*
57 * Fill a time series with stationary white Gaussian noise
58 */
59
60
61static void gaussian_noise(REAL8TimeSeries * series, double rms, gsl_rng * rng)
62{
63 unsigned i;
64
65 for(i = 0; i < series->data->length; i++)
66 series->data->data[i] = gsl_ran_gaussian(rng, rms);
67}
68
69
70/*
71 * compute semimajor and semiminor axes lengths from eccentricity assuming
72 * that a^2 + b^2 = 1. eccentricity is e = \sqrt{1 - (b / a)^2}. from
73 * those two constraints the following expressions are obtained.
74 */
75
76
77static void semi_major_minor_from_e(double e, double *a, double *b)
78{
79 double e2 = e * e;
80
81 *a = 1.0 / sqrt(2.0 - e2);
82 *b = *a * sqrt(1.0 - e2);
83}
84
85
86/*
87 * ============================================================================
88 *
89 * Utilities
90 *
91 * ============================================================================
92 */
93
94
95/**
96 * @brief Return the strain of the sample with the largest magnitude.
97 *
98 * @details
99 * The input must have non-zero length.
100 *
101 * @param[in] hplus A time series.
102 *
103 * @param[in] hcross A time series. Optional. Pass NULL to disregard.
104 *
105 * @param[out] index The index of the peak sample will be written to this address. Optional. NULL to disregard.
106 *
107 * @returns The strain of the sample with the largest magnitude. The \f$+\f$ polarization amplitude is in the real component, the imaginary component contains the \f$\times\f$ polarization's amplitude (or is 0 if hcross is not supplied).
108 *
109 * @retval XLAL_REAL8_FAIL_NAN Falure.
110 */
111
112
113COMPLEX16 XLALMeasureHPeak(const REAL8TimeSeries *hplus, const REAL8TimeSeries *hcross, unsigned *index)
114{
115 double complex hpeak;
116 double abs_hpeak;
117 unsigned i;
118
119 /* check input */
120
121 if(hcross) {
123 }
124 if(!hplus->data->length) {
125 XLALPrintError("%s(): length must be > 0\n", __func__);
127 }
128
129 /* find peak */
130
131 hpeak = hplus->data->data[0] + I * (hcross ? hcross->data->data[0] : 0.);
132 abs_hpeak = cabs(hpeak);
133 for(i = 1; i < hplus->data->length; i++)
134 if(cabs(hplus->data->data[i] + I * (hcross ? hcross->data->data[i] : 0.)) > abs_hpeak) {
135 hpeak = hplus->data->data[i] + I * (hcross ? hcross->data->data[i] : 0.);
136 abs_hpeak = cabs(hpeak);
137 if(index)
138 *index = i;
139 }
140
141 return hpeak;
142}
143
144
145/**
146 * @brief Computes the integral of the product of two time series.
147 *
148 * @details
149 * From two time series, \f$s_{1}\f$ and \f$s_{2}\f$, computes and returns
150 * \f{equation}{
151 * \int s_{1}(t) s_{2}(t) \diff t.
152 * \f}
153 *
154 * @param[in] s1 A time series.
155 *
156 * @param[in] s2 A time series.
157 *
158 * @returns The integral of the product.
159 *
160 * @retval XLAL_REAL8_FAIL_NAN Failure
161 */
162
163
165{
166 double e = 0.0;
167 double sum = 0.0;
168 unsigned i;
169
170 /* FIXME: this is overly strict, this function could be smarter */
171
173
174 /* Kahans's compensated summation algorithm */
175
176 for(i = 0; i < s1->data->length; i++) {
177 double tmp = sum;
178 /* what we want to add = s1 * s2 + "error from last
179 * iteration" */
180 double x = s1->data->data[i] * s2->data->data[i] + e;
181 /* add */
182 sum += x;
183 /* negative of what was actually added */
184 e = tmp - sum;
185 /* what didn't get added, add next time */
186 e += x;
187 }
188
189 return sum * s1->deltaT;
190}
191
192
193/**
194 * @brief Computes "root-sum-square strain", or \f$h_{\mathrm{rss}}\f$.
195 *
196 * @details In fact, this is
197 * \f{equation}{
198 * h_{\mathrm{rss}}
199 * = \sqrt{\sum (h_{+}^{2} + h_{x}^{2}) \Delta t},
200 * \f}
201 * (includes a factor of \f$\Delta t\f$), which is an approximation of the
202 * square root of the square integral, \f$\sqrt{\int (h_{+}^{2} +
203 * h_{x}^{2}) \diff t}\f$.
204 *
205 * The input time series must start and end at the same times and have the
206 * same sample rates.
207 *
208 * @param[in] hplus \f$h_{+}\f$ time series.
209 *
210 * @param[in] hcross \f$h_{\times}\f$ time series.
211 *
212 * @returns The \f$h_{\mathrm{rss}}\f$
213 *
214 * @retval XLAL_REAL8_FAIL_NAN Failure.
215 */
216
217
219 const REAL8TimeSeries *hplus,
220 const REAL8TimeSeries *hcross
221)
222{
223 return sqrt(XLALMeasureIntS1S2DT(hplus, hplus) + XLALMeasureIntS1S2DT(hcross, hcross));
224}
225
226
227/**
228 * @brief Computes the integral of the square of a real-valued time series'
229 * first derivative from its Fourier transform.
230 *
231 * @details
232 * Given the Fourier transform of a real-valued function \f$h(t)\f$,
233 * compute and return the integral of the square of its derivative,
234 * \f{equation}{
235 * \int \stackrel{.}{h}^{2} \diff t.
236 * \f}
237 * The normalization factors in this function assume that
238 * XLALREAL8FreqTimeFFT() will be used to convert the frequency series to
239 * the time domain.
240 *
241 * @param[in] fseries The Fourier transform of a real-valued function of
242 * time. See also XLALREAL8TimeFreqFFT().
243 *
244 * @returns \f$\int \stackrel{.}{h}^{2} \diff t\f$
245 *
246 * @retval XLAL_REAL8_FAIL_NAN Failure.
247 */
248
249
251{
252 unsigned i;
253 double e = 0.0;
254 double sum = 0.0;
255
256 /* Kahan's compensated summation algorithm. The summation is done
257 * from lowest to highest frequency under the assumption that high
258 * frequency components tend to add more to the magnitude of the
259 * derivative. Note that because only half the components of the
260 * Fourier transform are stored a factor of 2 is added after the
261 * sum. The DC component should only count once, but it does not
262 * contribute anything to the sum so no special case is required to
263 * handle it. */
264
265 for(i = 0; i < fseries->data->length; i++) {
266 double tmp = sum;
267 /* what we want to add = f^{2} |\tilde{s}(f)|^{2} + "error
268 * from last iteration" */
269 double x = pow(fseries->f0 + i * fseries->deltaF, 2) * pow(cabs(fseries->data->data[i]), 2) + e;
270 /* add */
271 sum += x;
272 /* negative of what was actually added */
273 e = tmp - sum;
274 /* what didn't get added, add next time */
275 e += x;
276 }
277
278 /* because we've only summed the positive frequency components */
279
280 sum *= 2;
281
282 /* 4 \pi^{2} \delta f */
283
284 sum *= LAL_TWOPI * LAL_TWOPI * fseries->deltaF;
285
286 return sum;
287}
288
289
290/**
291 * @brief Computes the areal energy density carried by a gravitational
292 * wave.
293 *
294 * @details
295 * The local gravitational wave flux density in the two independent
296 * polarizations, \f$h_{+}(t)\f$ and \f$h_{\times}(t)\f$, is [Isaacson
297 * 1968]
298 * \f{equation}{
299 * \frac{\diff E}{\diff A \diff t}
300 * = \frac{1}{16 \pi} \frac{c^{3}}{G} \left( \dot{h}_{+}^{2} +
301 * \dot{h}_{\times}^{2} \right).
302 * \f}
303 * For a source at non-cosmological distances (distances small enough that
304 * for spheres of that radius \f$A = 4 \pi r^{2}\f$), the equivalent
305 * isotropic radiated energy in a gravitational wave for a source at a
306 * distance \f$r\f$ is
307 * \f{equation}{
308 * E
309 * = \frac{c^{3}}{4 G} r^{2} \int \left( \dot{h}_{+}^{2}(t) +
310 * \dot{h}_{\times}^{2}(t) \right) \diff t.
311 * \f}
312 * Given \f$h_{+}(t)\f$ and \f$h_{\times}(t)\f$ in the waveframe, this
313 * function returns
314 * \f{equation}{
315 * \frac{E}{r^{2}}
316 * = \frac{c^{3}}{4 G} \int ( \stackrel{.}{h}_{+}^{2} +
317 * \stackrel{.}{h}_{\times}^{2} ) \diff t.
318 * \f}
319 *
320 * The input time series must start and end at the same times and have the
321 * same sample rates. The square integrals of the derivatives are
322 * evaluated in the frequency domain so this function implicitly assumes
323 * the input time series are periodic on their intervals. The calling code
324 * must ensure appropriate conditioning (e.g., tapering and padding) has
325 * been applied to the time series for this to be a good approximation.
326 * Waveforms that have been conditioned for use as software injections are
327 * almost certainly suitably conditioned for this function.
328 *
329 * @param[in] hplus The \f$h_{+}\f$ time series.
330 *
331 * @param[in] hcross The \f$h_{\times}\f$ time series.
332 *
333 * @returns
334 * Energy per unit area in Joules per square metre.
335 *
336 * @retval XLAL_REAL8_FAIL_NAN Falure.
337 */
338
339
341{
342 REAL8FFTPlan *plan;
343 COMPLEX16FrequencySeries *tilde_hplus, *tilde_hcross;
344 double e_over_rsquared;
345 unsigned i;
346
347 /* FIXME: this is overly strict, this function could be smarter */
348
350
351 /* transform to the frequency domain */
352
353 plan = XLALCreateForwardREAL8FFTPlan(hplus->data->length, 0);
354 tilde_hplus = XLALCreateCOMPLEX16FrequencySeries(NULL, &hplus->epoch, 0.0, 0.0, &lalDimensionlessUnit, hplus->data->length / 2 + 1);
355 tilde_hcross = XLALCreateCOMPLEX16FrequencySeries(NULL, &hcross->epoch, 0.0, 0.0, &lalDimensionlessUnit, hcross->data->length / 2 + 1);
356 if(!plan || !tilde_hplus || !tilde_hcross) {
361 }
362 i = XLALREAL8TimeFreqFFT(tilde_hplus, hplus, plan);
363 i |= XLALREAL8TimeFreqFFT(tilde_hcross, hcross, plan);
365 if(i) {
369 }
370
371 /* measure E / r^2 */
372
373 e_over_rsquared = (double) LAL_C_SI * LAL_C_SI * LAL_C_SI / (4 * LAL_G_SI) * (XLALMeasureIntHDotSquaredDT(tilde_hplus) + XLALMeasureIntHDotSquaredDT(tilde_hcross));
374
375 /* done */
376
379
380 return e_over_rsquared;
381}
382
383
384/*
385 * ============================================================================
386 *
387 * Construct a \delta Function Injection
388 *
389 * ============================================================================
390 */
391
392
393/**
394 * @brief Genereates a single-sample impulse waveform
395 *
396 * @details
397 * Places a single non-zero sample into the middle of the time series. The
398 * \f$h_{+}\f$ and \f$h_{\times}\f$ time series both have an odd number of
399 * samples all set to 0 except for a single sample with amplitude hpeak in
400 * the middle of the \f$h_{+}\f$ time series.
401 *
402 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
403 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
404 * failure.
405 *
406 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
407 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
408 * on failure.
409 *
410 * @param[in] hpeak Strain amplitude of the impulse.
411 *
412 * @param[in] delta_t Sample period of output time series in seconds.
413 *
414 * @retval 0 Success
415 * @retval <0 Failure
416 */
417
418
420 REAL8TimeSeries **hplus,
421 REAL8TimeSeries **hcross,
422 REAL8 hpeak,
423 REAL8 delta_t
424)
425{
427 /* length is 1 sample. XLALSimDetectorStrainREAL8TimeSeries() will
428 * add sufficient padding to accomodate the interpolation kernel on
429 * either side */
430 int length = 1;
431
432 /* the middle sample is t = 0 */
433
434 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t))
436
437 /* allocate the time series */
438
439 *hplus = XLALCreateREAL8TimeSeries("Impulse +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
440 *hcross = XLALCreateREAL8TimeSeries("Impulse x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
441 if(!*hplus || !*hcross) {
444 *hplus = *hcross = NULL;
446 }
447
448 /* set to zero */
449
450 memset((*hplus)->data->data, 0, length * sizeof(*(*hplus)->data->data));
451 memset((*hcross)->data->data, 0, length * sizeof(*(*hcross)->data->data));
452
453 /* put impulse into middle sample of h+ */
454
455 (*hplus)->data->data[(length - 1) / 2] = hpeak;
456
457 /* done */
458
459 return 0;
460}
461
462
463/*
464 * ============================================================================
465 *
466 * Construct a Band- and Time-Limited White Noise Burst
467 *
468 * ============================================================================
469 */
470
471
472/**
473 * @brief Generate a band- and time-limited white-noise burst waveform
474 * with Gaussian envelopes in the time and frequency domains.
475 *
476 * @details
477 * Generates two time series containing \f$h_{+}(t)\f$ and \f$h_{x}(t)\f$,
478 * with the time-domain Gaussian envelope's peak located at \f$t = 0\f$ (as
479 * defined by the epoch and deltaT). The \f$+\f$ and \f$\times\f$ time
480 * series are statistically independent.
481 *
482The construction of a BTLWNB waveform with duration \f$\Delta t\f$ and
483bandwidth \f$\Delta f\f$ centred on \f$f_{0}\f$ begins by populating a time
484series with independent Gaussian random numbers. The origin of the time
485co-ordinate corresponds to the middle sample in the time series. We apply
486an initial time-limiting window function to the time series by multiplying
487the time series with a Gaussian window function
488\f{equation}{
489w_{1}(t)
490 \propto \ee^{-\frac{1}{2} t^{2} / \sigma_{t}^{2}},
491\f}
492where \f$\sigma_{t}\f$ sets the duration of the window. The windowed time
493series is then Fourier transformed and a second Gaussian window applied in
494the frequency domain
495\f{equation}{
496\tilde{w}_{2}(f)
497 \propto \ee^{-\frac{1}{2} (f - f_{0})^{2} / \sigma_{f}^{2}},
498\f}
499where \f$\sigma_{f} = \frac{1}{2} \Delta f\f$.
500
501Since the inital time series is real-valued, the negative frequency
502components of the Fourier transform are the complex conjugates of the
503positive frequency components and need not be stored. The frequency-domain
504filter is real-valued (phase preserving), and so when the positive
505frequency components are the only ones being stored applying the window
506function to them alone achieves the correct result.
507
508The multiplication of the frequency domain data by the window function is
509equivalent to convolving the time domain data with the Fourier transform of
510the window. Since the Fourier transform of the frequency window is not a
511\f$\delta\f$ function, the application of the band-limiting window has the
512effect of spreading the signal in the time domain, i.e.\ increasing its
513duration. We can compensate for this by choosing an appropriate value for
514\f$\sigma_{t}\f$ so that the waveform has the correct duration \e after
515application of the frequency domain window. The inverse Fourier transform
516of \f$\tilde{w}_{2}(f)\f$ is
517\f{equation}{
518w_{2}(t)
519 \propto \ee^{-2 \pi^{2} \sigma_{f}^{2} t^{2}}.
520\f}
521The result of convolving two Gaussians with one another is another
522Gaussian, so the effective time-domain window is
523\f{equation}{
524w(t)
525 = w_{1}(t) \otimes w_{2}(t)
526 \propto \ee^{-\frac{1}{2} t^{2} / \sigma^{2}},
527\f}
528where
529\f{equation}{
530\sigma^{2}
531 = \sigma_{t}^{2} + \frac{1}{4 \pi^{2} \sigma_{f}^{2}}
532 = \sigma_{t}^{2} + \frac{1}{\pi^{2} \Delta f^{2}}
533\f}
534We wish this Gaussian's width to be \f$\sigma = \frac{1}{2} \Delta t\f$,
535therefore
536\f{equation}{
537\sigma_{t}
538 = \sqrt{\frac{1}{4} \Delta t^{2} - \frac{1}{\pi^{2} \Delta f^{2}}}.
539\f}
540Note that \f$\sigma_{t}\f$ is only real-valued when
541\f{equation}{
542\Delta t \Delta f
543 \geq \frac{2}{\pi}.
544\f}
545
546After application of the frequency domain window the data is inverse
547transformed to the time domain for injection into the strain data.
548
549### Details
550
551This function produces both \f$h_{+}\f$ and \f$h_{\times}\f$ waveforms.
552These are independent waveforms constructed by applying the time series
553construction algorithm twice. The length of the result is \f$21 \Delta
554t\f$ rounded to the nearest odd integer,
555\f{equation}{
556L
557 = 2 \left\lfloor \frac{1}{2} \frac{21 \Delta t}{\delta t} \right\rfloor
558 + 1
559\f}
560where \f$\delta t\f$ is the sample period of the time series. The middle
561sample is \f$t = 0\f$, so the first and last samples are at \f$t = \pm \delta
562t (L - 1) / 2\f$. The time-domain Gaussian window is constructed with a
563call to <tt>XLALCreateGaussREAL8Window()</tt> with a shape parameter of
564\f{equation}{
565\beta
566 = \frac{(L - 1) \delta t / 2}{\sigma_{t}}.
567\f}
568The numerator transforms the normalized co-ordinate \f$y \in [-1, +1]\f$ in
569the definition of the window function to \f$t\f$. (See the LAL
570documentation for more information. Sample index 0 is \f$y = -1\f$, sample
571index \f$L - 1\f$ is \f$y = +1\f$, so there are \f$(L - 1) / 2\f$ sample indexes
572per unit of \f$y\f$.)
573
574The time series is transformed to the frequency domain with a call to
575<tt>XLALREAL8TimeFreqFFT()</tt>, which populates the metadata of the output
576frequency series with the appropriate values. There are \f$(L + 1) / 2\f$
577complex-valued frequency components with a bin spacing of \f$\delta f = (L
578\delta t)^{-1}\f$. The frequency domain Gaussian window is constructed with
579a call to <tt>XLALCreateGaussREAL8Window()</tt> requesting a window with a
580length of \f$L + 2\f$ (twice the length of the frequency series rounded up to
581the next odd integer), and a shape parameter of
582\f{equation}{
583\beta
584 = \frac{(L + 1) \delta f / 2}{\sigma_{f}}.
585\f}
586The numerator in the shape parameter converts the normalized co-ordinate
587\f$y \in [-1, +1]\f$ in the definition of the window function to
588frequency. (See the LAL documentation for more information. The
589window has \f$L + 2\f$ samples, sample index 0 is \f$y = -1\f$, sample index
590\f$L + 1\f$ is \f$y = +1\f$, so there are \f$(L + 1) / 2\f$ sample indexes per
591unit of \f$y\f$.) The window is created with the peak in the middle sample
592at index \f$(L + 1) / 2\f$, and we use <tt>XLALResizeREAL8Sequence()</tt> to
593extract as many samples as there are in the frequency series with the peak
594shifted to the correct bin. We want the peak to be at sample index \f$f_{0}
595/ \delta f\f$, so we extract \f$(L + 1) / 2\f$ samples starting at index \f$(L
596+ 1) / 2 - \lfloor f_{0} / \delta f + 0.5 \rfloor\f$.
597
598Following application of the frequency-domain window, the injection is
599transformed back to the time domain with a call to
600<tt>XLALREAL8FreqTimeFFT()</tt>. If \f$\tilde{h}_{k}\f$ are the complex
601values in the frequency bins, the output time series is
602\f{equation}{
603h_{j}
604 = \delta f \sum_{k = 0}^{L - 1} \tilde{h}_{k} \ee^{2 \pi \aye j k / L}
605 = \delta f \sum_{k = 0}^{L - 1} \tilde{h}_{k} \ee^{2 \pi \aye t k / (L
606 \delta t)},
607\f}
608where \f$t = j \delta t\f$. Differentiating with respect to \f$t\f$,
609\f{equation}{
610\dot{h}_{j}
611 = \delta f \sum_{k = 0}^{L - 1} \left( \frac{2 \pi \aye k}{L \delta t}
612 \right) \tilde{h}_{k} \ee^{2 \pi \aye j k / L},
613\f}
614and so
615\f{align}{
616\sum_{j = 0}^{L - 1} \dot{h}_{j}^{2} \delta t
617 & = \delta f^{2} \delta t \sum_{k = 0}^{L - 1} \sum_{k' = 0}^{L - 1}
618 \left( \frac{4 \pi^{2} k k'}{L^{2} \delta t^{2}} \right) \tilde{h}_{k}
619 \conj{\tilde{h}_{k'}} \sum_{j = 0}^{L - 1} \ee^{2 \pi \aye j (k - k') /
620 L}
621 \\
622 & = \delta f^{2} L \delta t \sum_{k = 0}^{L - 1} \left( \frac{4 \pi^{2}
623 k^{2}}{L^{2} \delta t^{2}} \right) \magnitude{\tilde{h}_{k}}^{2}
624 \\
625 & = 4 \pi^{2} \delta f \sum_{k = 0}^{L - 1} (k \delta f)^{2}
626 \magnitude{\tilde{h}_{k}}^{2}.
627\f}
628This relationship is used to normalize the injection time series. The
629expression on the left hand side is \f$\int \dot{h}^{2} \diff t\f$. For both
630polarizations the right hand side is computed in the frequency domain
631following application of the Gaussian window, and the amplitudes of the
632frequency components scaled prior to conversion to the time domain so that
633\f$\int (\dot{h}_{+}^{2} + \dot{h}_{\times}^{2}) \diff t\f$ has the desired
634value.
635
636To ensure no discontinuities in the strain time series when the injection
637is added to it, a final Tukey window is applied to the injection in the
638time domain. The Tukey window is constructed with a call to
639<tt>XLALCreateTukeyREAL8Window()</tt> with a shape parameter of \f$\beta =
6400.5\f$ so that the tapers span a total of 50\% of the time series.
641Because the Tukey window is flat with unit amplitude in the middle, it has
642no effect on the injection time series where the bulk of the energy is
643concentrated, and the large tapers ensure the Tukey window induces
644negligble spread of the injection in the frequency domain. Because the
645injection is normalized in the frequency domain prior to transformation to
646the time domain, the application of the Tukey window does bias the
647normalization slightly by reducing the total energy in the injection,
648however the Tukey window's tapers start several \f$\sigma_{t}\f$ away from
649the injection's peak and so this effect is negligble.
650
651In order that the waveforms be reproducable so that an analysis can be
652repeated, or the waveforms constructed multiple times for injection into
653the strain data from more than one instrument, it is necessary to specify
654how the initial time series of independent Gaussian random numbers is to be
655constructed. This is done by specifying the seed to be used with the
656random number generator. The random number generator is not specified, so
657the same seed may produce different injections with different versions of
658the code, but a seed and revision tag combination should be guaranteed to
659produce the same injection. Note also that changing the length of the
660injection time series changes the number of random numbers used to
661construct it, so the injection waveform also depends on the time series'
662sample rate. One has to be careful when constructing injection waveforms
663for instruments with different sample rates (e.g., LIGO and VIRGO). The
664injection must be constructed at the same sample rate for both instruments
665and then up- or down-sampled as needed when injected into each instrument's
666time series.
667
668\anchor xlalsimburstbtlwnb_examples
669\image html lalsimburst_btlwnbexamples.svg
670Example of the \f$+\f$ and \f$\times\f$ polarizations of a band- and
671time-limited white-noise burst injection waveforms with different degrees
672of freedom.
673 *
674 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
675 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
676 * failure.
677 *
678 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
679 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
680 * on failure.
681 *
682 * @param[in] duration Width of the Gaussian envelope in the time domain in
683 * seconds. The time domain envelope is \f$\propto \exp ( -\frac{1}{2}
684 * t^{2} / \mathrm{duration}^{2} )\f$
685 *
686 * @param[in] frequency Centre frequency, \f$f_{0}\f$, of the Gaussian
687 * envelope in the frequency domain in Hertz.
688 *
689 * @param[in] bandwidth Width of the Gaussian envelope in the frequency
690 * domain in Hertz. The frequency domain envelope is \f$\propto \exp (
691 * -\frac{1}{2} (f - f_{0})^{2} / \mathrm{bandwidth}^{2} )\f$
692 *
693 * @param[in] eccentricity The eccentricity, \f$\epsilon = \sqrt{1 -
694 * ({h_{0}}_{\times} / {h_{0}}_{+})^{2}}\f$, of the polarization ellipse
695 * setting the relative amplitudes of the \f$h_{+}\f$ and \f$h_{\times}\f$
696 * components' Gaussian envelopes. With eccentricity = 0 the two
697 * components have equal amplitudes (circularly polarized); with
698 * eccentricity = 1 the amplitude of the \f$h_{\times}\f$ component is 0
699 * (linearly polarized). Note that this controls the relationship between
700 * the expected amplitudes, not the realized amplitudes.
701 *
702 * @param[in] phase The phase, \f$\phi\f$, of the sinusoidal oscillations
703 * that get multiplied by the Gaussian envelope. With \f$\phi=0\f$,
704 * \f$h_{+}\f$ is cosine-like and \f$h_{\times}\f$ is sine-like. With
705 * \f$\phi=\pi/2\f$, \f$h_{+}\f$ is sine-like and \f$h_{\times}\f$ is
706 * cosine-like.
707 *
708 * @param[in] int_hdot_squared The output is normalized so that \f$\int
709 * (\stackrel{.}{h}_{+}^{2} + \stackrel{.}{h}_{\times}^{2}) \diff t\f$
710 * equals this. Note that the normalization is not on the expected
711 * amplitude of the waveform but on the realized amplitude of the waveform.
712 *
713 * @param[in] delta_t Sample period of output time series in seconds.
714 *
715 * @param[in] rng GSL random number generator instance. Will be used to
716 * generate normally distributed random variables to seed the
717 * \f$h_{+}(t)\f$ and \f$h_{x}(t)\f$ components.
718 *
719 * @retval 0 Success
720 * @retval <0 Failure
721 *
722 * @note
723 * Because the injection is constructed with a random number generator, any
724 * changes to this function that change how random numbers are chosen will
725 * indirectly have the effect of altering the relationship between
726 * injection waveform and random number seed. For example, increasing the
727 * length of the time series will change the injection waveforms. There's
728 * nothing wrong with this, the waveforms are still correct, but if there
729 * is a need to reproduce a waveform exactly then it will be necessary to
730 * tag the code before making such changes.
731 *
732 * @note
733 * The algorithm's low degree-of-freedom limit is equivalent to
734 * XLALSimBurstSineGaussian() but instead of Q and centre frequency the
735 * duration and centre frequency are the degrees of freedom, which allows
736 * the algorithm to also be evaluated in the low-frequency limit where
737 * (when eccentricity = 1) it yields output equivalent to
738 * XLALSimBurstGaussian(). If 2-degree-of-freedom waveforms or Gaussian
739 * waveforms are required, the other functions are substantially more
740 * efficient ways to generate them, but this function provides an interface
741 * that yields sine-Gaussian family waveforms that is valid in all regimes.
742 */
743
744
746 REAL8TimeSeries **hplus,
747 REAL8TimeSeries **hcross,
749 REAL8 frequency,
750 REAL8 bandwidth,
751 REAL8 eccentricity,
752 REAL8 phase,
753 REAL8 int_hdot_squared,
754 REAL8 delta_t,
755 gsl_rng *rng
756)
757{
758 int length;
759 double a, b;
761 COMPLEX16FrequencySeries *tilde_hplus, *tilde_hcross;
762 REAL8Window *window;
763 REAL8FFTPlan *plan;
764 REAL8 norm_factor;
765 /* compensate the width of the time-domain window's envelope for
766 * the broadening will be induced by the subsequent application of
767 * the frequency-domain envelope */
768 REAL8 sigma_t_squared = duration * duration / 4.0 - 1.0 / (LAL_PI * LAL_PI * bandwidth * bandwidth);
769 unsigned i;
770
771 /* check input. checking if sigma_t_squared < 0 is equivalent to
772 * checking if duration * bandwidth < LAL_2_PI */
773
774 if(duration < 0 || frequency < 0 || bandwidth < 0 || eccentricity < 0 || eccentricity > 1 || sigma_t_squared < 0 || int_hdot_squared < 0 || delta_t <= 0) {
775 XLALPrintError("%s(): invalid input parameters\n", __func__);
776 *hplus = *hcross = NULL;
778 }
779
780 /* length of the injection time series is 21 * duration, rounded to
781 * the nearest odd integer. this length is chosen because it works
782 * well for sine-Gaussians, but I have no metric for testing the
783 * quality of the result here. */
784
785 length = (int) floor(21.0 * duration / delta_t / 2.0);
786 length = 2 * length + 1;
787
788 /* the middle sample is t = 0 */
789
790 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t))
792
793 /* allocate the time series */
794
795 *hplus = XLALCreateREAL8TimeSeries("BTLWNB +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
796 *hcross = XLALCreateREAL8TimeSeries("BTLWNB x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
797 if(!*hplus || !*hcross) {
800 *hplus = *hcross = NULL;
802 }
803
804 /* fill with independent zero-mean unit variance Gaussian random
805 * numbers (any non-zero amplitude is OK, it will be adjusted
806 * later) */
807
808 gaussian_noise(*hplus, 1, rng);
809 gaussian_noise(*hcross, 1, rng);
810
811 /* apply the time-domain Gaussian window. the window function's
812 * shape parameter is ((length - 1) / 2) / (\sigma_{t} / delta_t) where
813 * \sigma_{t} is the compensated time-domain window duration */
814
815 window = XLALCreateGaussREAL8Window((*hplus)->data->length, (((*hplus)->data->length - 1) / 2) / (sqrt(sigma_t_squared) / delta_t));
816 if(!window) {
819 *hplus = *hcross = NULL;
821 }
822 for(i = 0; i < window->data->length; i++) {
823 (*hplus)->data->data[i] *= window->data->data[i];
824 (*hcross)->data->data[i] *= window->data->data[i];
825 }
827
828 /* transform to the frequency domain */
829
830 plan = XLALCreateForwardREAL8FFTPlan((*hplus)->data->length, 0);
831 tilde_hplus = XLALCreateCOMPLEX16FrequencySeries(NULL, &epoch, 0.0, 0.0, &lalDimensionlessUnit, (*hplus)->data->length / 2 + 1);
832 tilde_hcross = XLALCreateCOMPLEX16FrequencySeries(NULL, &epoch, 0.0, 0.0, &lalDimensionlessUnit, (*hcross)->data->length / 2 + 1);
833 if(!plan || !tilde_hplus || !tilde_hcross) {
839 *hplus = *hcross = NULL;
841 }
842 i = XLALREAL8TimeFreqFFT(tilde_hplus, *hplus, plan);
843 i |= XLALREAL8TimeFreqFFT(tilde_hcross, *hcross, plan);
845 if(i) {
850 *hplus = *hcross = NULL;
852 }
853
854 /* apply the frequency-domain Gaussian window. the window
855 * function's shape parameter is computed similarly to that of the
856 * time-domain window, with \sigma_{f} = \Delta f / 2. the window
857 * is created with its peak on the middle sample, which we need to
858 * shift to the sample corresponding to the injection's centre
859 * frequency. we also apply the eccentricity amplitude adjustments
860 * at this stage (last chance before the overall normalization is
861 * computed). */
862
863 semi_major_minor_from_e(eccentricity, &a, &b);
864 {
865 double beta = -0.5 / (bandwidth * bandwidth / 4.);
866 for(i = 0; i < tilde_hplus->data->length; i++) {
867 double f = (tilde_hplus->f0 + i * tilde_hplus->deltaF) - frequency;
868 double w = f == 0. ? 1. : exp(f * f * beta);
869 tilde_hplus->data->data[i] *= a * w;
870 tilde_hcross->data->data[i] *= b * w;
871 /* rotate phases of non-DC components */
872 if(i != 0) {
873 tilde_hplus->data->data[i] *= cexp(-I * phase);
874 tilde_hcross->data->data[i] *= I * cexp(-I * phase);
875 }
876 }
877 }
878
879 /* normalize the waveform to achieve the desired \int
880 * \f$(\stackrel{.}{h}_{+}^{2} + \stackrel{.}{h}_{\times}^{2}) dt\f$ */
881
882 norm_factor = sqrt((XLALMeasureIntHDotSquaredDT(tilde_hplus) + XLALMeasureIntHDotSquaredDT(tilde_hcross)) / int_hdot_squared);
883 if(int_hdot_squared == 0 || norm_factor == 0) {
888 *hplus = *hcross = NULL;
890 }
891 for(i = 0; i < tilde_hplus->data->length; i++) {
892 tilde_hplus->data->data[i] /= norm_factor;
893 tilde_hcross->data->data[i] /= norm_factor;
894 }
895
896 /* transform to the time domain */
897
898 plan = XLALCreateReverseREAL8FFTPlan((*hplus)->data->length, 0);
899 if(!plan) {
904 *hplus = *hcross = NULL;
906 }
907 i = XLALREAL8FreqTimeFFT(*hplus, tilde_hplus, plan);
908 i |= XLALREAL8FreqTimeFFT(*hcross, tilde_hcross, plan);
912 if(i) {
915 *hplus = *hcross = NULL;
917 }
918
919 /* force the sample rate incase round-off has shifted it a bit */
920
921 (*hplus)->deltaT = (*hcross)->deltaT = delta_t;
922 /* apply a Tukey window for continuity at the start and end of the
923 * injection. the window's shape parameter sets what fraction of
924 * the window is used by the tapers */
925
926 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
927 if(!window) {
930 *hplus = *hcross = NULL;
932 }
933 for(i = 0; i < window->data->length; i++) {
934 (*hplus)->data->data[i] *= window->data->data[i];
935 (*hcross)->data->data[i] *= window->data->data[i];
936 }
938
939 /* done */
940
941 return 0;
942}
943
944/*
945 * ============================================================================
946 *
947 * SineGaussian and Friends
948 *
949 * ============================================================================
950 */
951
952/**
953 * @brief Compute the Q of a sine-Gaussian waveform from the duration and
954 * centre frequency.
955 *
956 * @details The relationship is
957 * \f{equation}{
958 * Q
959 * = 2 \pi f_{0} \Delta t.
960 * \f}
961 * The result becomes independent of duration at 0 Hz.
962 *
963 * @param[in] duration The duration, \f$\Delta t\f$, of the sine-Gaussian in
964 * seconds.
965 *
966 * @param[in] centre_frequency The centre frequency, \f$f_{0}\f$, of the
967 * sine-Gaussian in Hertz.
968 *
969 * @retval Q The \f$Q\f$ of the sine-Gaussian.
970 *
971 * See also: XLALSimBurstSineGaussianDuration()
972 */
973
974
976 double duration,
977 double centre_frequency
978)
979{
980 return LAL_TWOPI * duration * centre_frequency;
981}
982
983
984/**
985 * @brief Compute the duration of a sine-Gaussian waveform from the Q and centre
986 * frequency.
987 *
988 * @details The relationship is
989 * \f{equation}{
990 * Q
991 * = 2 \pi f_{0} \Delta t.
992 * \f}
993 * The relationship is undefined at 0 Hz.
994 *
995 * @param[in] Q The \f$Q\f$ of the sine-Gaussian.
996 *
997 * @param[in] centre_frequency The centre frequency, \f$f_{0}\f$, of the
998 * sine-Gaussian in Hertz.
999 *
1000 * @retval duration The duration of the sine-Gaussian, \f$\Delta t\f$, in
1001 * seconds.
1002 *
1003 * See also: XLALSimBurstSineGaussianQ()
1004 */
1005
1006
1008 double Q,
1009 double centre_frequency
1010)
1011{
1012 double duration = Q / (LAL_TWOPI * centre_frequency);
1013 if(!isfinite(duration))
1015 return duration;
1016}
1017
1018
1019/**
1020 * @brief Generate sine- and cosine-Gaussian waveforms with various
1021 * polarizations and phases.
1022 *
1023 * @details
1024 * Generates two time series, \f$h_{+}\f$ and \f$h_{\times}\f$, containing
1025 * add-mixtures of cosine-Gaussian and sine-Gaussian waveforms. The
1026 * Gaussian envelope peaks in both at t = 0 as defined by epoch and deltaT.
1027 * By setting the eccentricity and phase to appropriate values any
1028 * linearly, elliptically, or cicularly polarized sine- or cosine-Gaussian
1029 * waveform can be generated. The dominant polarization is placed in the
1030 * \f$h_{+}\f$ component.
1031 *
1032 * A Tukey window is applied to make the waveform go to 0 smoothly at the
1033 * start and end.
1034 *
1035 * \anchor xlalsimburstsinegaussian_examples
1036 * \image html lalsimburst_sinegaussianexamples.svg "Sine-Gaussian examples."
1037 *
1038 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1039 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1040 * failure.
1041 *
1042 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1043 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1044 * on failure.
1045 *
1046 * @param[in] Q The "Q" of the waveform. The Gaussian envelope is
1047 * \f$\propto \exp(-\frac{1}{2} t^{2} / \sigma_{t}^{2})\f$ where
1048 * \f$\sigma_{t} = Q / (2 \pi f)\f$. See also XLALSimBurstSineGaussianQ()
1049 * and XLALSimBurstSineGaussianDuration().
1050 *
1051 * @param[in] centre_frequency The frequency of the sinusoidal oscillations
1052 * that get multiplied by the Gaussian envelope.
1053 *
1054 * @param[in] hrss The \f$h_{\mathrm{rss}}\f$ of the waveform to be
1055 * generated. See K. Riles, LIGO-T040055-00.pdf. This function normalizes
1056 * the waveform algebraically assuming it to be an ideal sine-Gaussian
1057 * (continuous in time, with no time boundaries and no tapering window), so
1058 * the actual numerical normalization might be slightly different. See
1059 * also XLALMeasureHrss().
1060 *
1061 * @param[in] eccentricity The eccentricity, \f$\epsilon = \sqrt{1 -
1062 * ({h_{0}}_{\times} / {h_{0}}_{+})^{2}}\f$, of the polarization ellipse
1063 * setting the relative amplitudes of the \f$h_{+}\f$ and \f$h_{\times}\f$
1064 * components' Gaussian envelopes. With eccentricity = 0 the two
1065 * components have equal amplitudes (circularly polarized); with
1066 * eccentricity = 1 the amplitude of the \f$h_{\times}\f$ component is 0
1067 * (linearly polarized).
1068 *
1069 * @param[in] phase The phase, \f$\phi\f$, of the sinusoidal oscillations
1070 * that get multiplied by the Gaussian envelope. With \f$\phi=0\f$,
1071 * \f$h_{+}\f$ is cosine-like and \f$h_{\times}\f$ is sine-like. With
1072 * \f$\phi=\pi/2\f$, \f$h_{+}\f$ is sine-like and \f$h_{\times}\f$ is
1073 * cosine-like.
1074 *
1075 * @param[in] delta_t Sample period of output time series in seconds.
1076 *
1077 * @retval 0 Success
1078 * @retval <0 Failure
1079 */
1081 REAL8TimeSeries **hplus,
1082 REAL8TimeSeries **hcross,
1083 REAL8 Q,
1084 REAL8 centre_frequency,
1085 REAL8 hrss,
1086 REAL8 eccentricity,
1087 REAL8 phase,
1088 REAL8 delta_t
1089)
1090{
1091 REAL8Window *window;
1092 /* square integral of unit amplitude cosine- and sine-Gaussian
1093 * waveforms. the sine-Gaussian case is derived in K. Riles,
1094 * LIGO-T040055-00.pdf, equation (7). the cosine-Gaussian case is
1095 * obtained by replacing cos^2 with 1-sin^2, using equation (5) and
1096 * the result for sine-Gaussians. */
1097 const double cgsq = Q / (4.0 * centre_frequency * sqrt(LAL_PI)) * (1.0 + exp(-Q * Q));
1098 const double sgsq = Q / (4.0 * centre_frequency * sqrt(LAL_PI)) * (1.0 - exp(-Q * Q));
1099 /* semimajor and semiminor axes of waveform ellipsoid. */
1100 double a, b;
1101 semi_major_minor_from_e(eccentricity, &a, &b);
1102 /* peak amplitudes of plus and cross */
1103 double cosphase = cos(phase);
1104 double sinphase = sin(phase);
1105 const double h0plus = hrss * a / sqrt(cgsq * cosphase * cosphase + sgsq * sinphase * sinphase);
1106 const double h0cross = hrss * b / sqrt(cgsq * sinphase * sinphase + sgsq * cosphase * cosphase);
1108 int length;
1109 unsigned i;
1110 /* don't compute these in loops */
1111 const double negative2Qsquared = -2. * Q * Q;
1112 const double twopif0 = LAL_TWOPI * centre_frequency;
1113 /* some pointers */
1114 double *hp, *hc, *w;
1115
1116 /* check input. */
1117
1118 if(Q < 0 || centre_frequency < 0 || hrss < 0 || eccentricity < 0 || eccentricity > 1 || delta_t <= 0) {
1119 XLALPrintError("%s(): invalid input parameters\n", __func__);
1120 *hplus = *hcross = NULL;
1122 }
1123
1124 /* length of the injection time series is 21 * the width of the
1125 * Gaussian envelope (sigma_t in the comments above), rounded to
1126 * the nearest odd integer. experiments suggest that that's the
1127 * minimum length without the hrss of the output deviating from the
1128 * requested hrss by more than numerical noise. */
1129
1130 length = (int) floor(21.0 * Q / centre_frequency / LAL_TWOPI / delta_t / 2.0);
1131 length = 2 * length + 1;
1132
1133 /* the middle sample is t = 0 */
1134
1135 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t))
1137
1138 /* allocate the time series */
1139
1140 *hplus = XLALCreateREAL8TimeSeries("sine-Gaussian +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1141 *hcross = XLALCreateREAL8TimeSeries("sine-Gaussian x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1142 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
1143 if(!*hplus || !*hcross || !window) {
1146 XLALDestroyREAL8Window(window);
1147 *hplus = *hcross = NULL;
1149 }
1150
1151 /* populate */
1152
1153 hp = (*hplus)->data->data;
1154 hc = (*hcross)->data->data;
1155 w = window->data->data;
1156 for(i = 0; i < (*hplus)->data->length; i++) {
1157 const double t = ((int) i - (length - 1) / 2) * delta_t;
1158 const double phi = twopif0 * t;
1159 const complex double fac = cexp(phi * phi / negative2Qsquared + I * (phi - phase)) * w[i];
1160 hp[i] = h0plus * creal(fac);
1161 hc[i] = h0cross * cimag(fac);
1162 }
1163 XLALDestroyREAL8Window(window);
1164
1165 /* done */
1166
1167 return 0;
1168}
1169
1170
1171/**
1172 * @brief Generate Gaussian waveforms.
1173 *
1174 * @details
1175 * The burst working group has traditionally treated these as a distinct
1176 * class of waveform rather than, say, the low-frequency limit of the
1177 * sine-Gaussian class of waveform. Therefore, for convenience, a separate
1178 * interface is provided to generate these waveforms.
1179 *
1180 * Generates two time series, \f$h_{+}\f$ and \f$h_{\times}\f$, containing
1181 * a Gaussian in \f$h_{+}\f$. \f$h_{\times}\f$ is set to 0. The Gaussian
1182 * peaks at t = 0 as defined by epoch and deltaT. The degrees of freedom
1183 * are the duration and the \f$h_{\mathrm{rss}}\f$. The function is
1184 * \f{equation}{
1185 * h_{+}(t)
1186 * = \frac{h_{\mathrm{rss}}}{\sqrt{\sqrt{\pi} \Delta t}} \exp -\frac{1}{2} \frac{t^{2}}{\Delta t^{2}}.
1187 * \f}
1188 *
1189 * A Tukey window is applied to make the waveform go to 0 smoothly at the
1190 * start and end.
1191 *
1192 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1193 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1194 * failure.
1195 *
1196 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1197 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1198 * on failure.
1199 *
1200 * @param[in] duration The width of the Gaussian, \f$\Delta t\f$.
1201 *
1202 * @param[in] hrss The \f$h_{\mathrm{rss}}\f$ of the waveform to be
1203 * generated. This function normalizes the waveform algebraically assuming
1204 * it to be an ideal Gaussian (continuous in time, with no time boundaries
1205 * and no tapering window), so the actual numerical normalization might be
1206 * slightly different. See also XLALMeasureHrss().
1207 *
1208 * @param[in] delta_t Sample period of output time series in seconds.
1209 *
1210 * @retval 0 Success
1211 * @retval <0 Failure
1212 */
1213
1214
1216 REAL8TimeSeries **hplus,
1217 REAL8TimeSeries **hcross,
1219 REAL8 hrss,
1220 REAL8 delta_t
1221)
1222{
1223 REAL8Window *window;
1224 const double h0plus = hrss / sqrt(sqrt(LAL_PI) * duration);
1226 int i, length;
1227
1228 /* check input. */
1229
1230 if(duration < 0 || hrss < 0 || !isfinite(h0plus) || delta_t <= 0) {
1231 XLALPrintError("%s(): invalid input parameters\n", __func__);
1232 *hplus = *hcross = NULL;
1234 }
1235
1236 /* length of the injection time series is 21 * the width of the
1237 * Gaussian envelope, because that's what works well for
1238 * sine-Gaussians */
1239
1240 length = (int) floor(21.0 * duration / delta_t / 2.0);
1241 length = 2 * length + 1;
1242
1243 /* the middle sample is t = 0 */
1244
1245 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t))
1247
1248 /* allocate the time series */
1249
1250 *hplus = XLALCreateREAL8TimeSeries("Gaussian +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1251 *hcross = XLALCreateREAL8TimeSeries("Gaussian x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1252 window = XLALCreateTukeyREAL8Window(length, 0.5);
1253 if(!*hplus || !*hcross || !window) {
1256 XLALDestroyREAL8Window(window);
1257 *hplus = *hcross = NULL;
1259 }
1260
1261 /* populate */
1262
1263 for(i = 0; i < (length - 1) / 2; i++) {
1264 const double t = ((int) i - (length - 1) / 2) * delta_t;
1265 (*hplus)->data->data[i] = (*hplus)->data->data[length - 1 - i] = h0plus * exp(-0.5 * t * t / (duration * duration)) * window->data->data[i];
1266 }
1267 (*hplus)->data->data[i] = h0plus;
1268 memset((*hcross)->data->data, 0, (*hcross)->data->length * sizeof(*(*hcross)->data->data));
1269
1270 XLALDestroyREAL8Window(window);
1271
1272 /* done */
1273
1274 return 0;
1275}
1276
1277
1278/*
1279 * ============================================================================
1280 *
1281 * Strings
1282 *
1283 * ============================================================================
1284 */
1285
1286
1287/**
1288 * @brief Function for generating cosmic string waveforms.
1289 *
1290 * @details
1291 * Generates the \f$h_{+}\f$ and \f$h_{\times}\f$ components of a cosmic
1292 * string cusp, kink, and kink-kink waveform. These waveforms are linearly
1293 * polarized and placed in the \f$h_{+}\f$ compnent. The \f$h_{\times}\f$
1294 * component is set to 0. The waveform peaks at t = 0 (as defined by the
1295 * epoch and deltaT)
1296 *
1297 * In the frequency domain, the waveform is \f$A f^{-q}\f$ with a
1298 * (non-physical) low-frequency cut-off and a (physical) high-frequency
1299 * cut-off. For kink-kinks the high-frequency cutoff doesn't exist, and
1300 * the argument given is ignored.
1301 * \f{equation}{
1302 * \tilde{h}_{+}(f)
1303 * = A f^{-q} \left(1 +
1304 * \frac{f_{\mathrm{low}}^{2}}{f^{2}}\right)^{-4} \begin{cases} \exp(1 -
1305 * f/f_{\mathrm{high}}) & f > f_{\mathrm{high}} \\ 1 & f \leq
1306 * f_{\mathrm{high}} \end{cases}
1307 * \f}
1308 *
1309 * The output has a Tukey window applied to force it to go to 0 smoothly at
1310 * the start and end. The low frequnecy cut-off is fixed at
1311 * \f$f_{\mathrm{low}} = 1 \mathrm{Hz}\f$, so these waveforms should be
1312 * high-pass filtered before being used as injections or search templates.
1313 *
1314 * \anchor xlalgeneratestringcusp_examples
1315 * \image html lalsimburst_stringcuspexamples.svg "String cusp examples."
1316 *
1317 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1318 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1319 * failure.
1320 *
1321 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1322 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1323 * on failure.
1324 *
1325 * @param[in] waveform Name of waveform. Should be cusp, kink, or kinkkink.
1326 *
1327 * @param[in] amplitude Waveform's amplitude parameter, \f$A\f$, in units
1328 * of \f$\mathrm{strain}\,\mathrm{s}^{-\frac{1}{3}}\f$.
1329 *
1330 * @param[in] f_high High frequency cut-off, \f$f_{\mathrm{high}}\f$, in
1331 * Hertz.
1332 *
1333 * @param[in] delta_t Sample period of output time series in seconds.
1334 *
1335 * @retval 0 Success
1336 * @retval <0 Failure
1337 */
1338
1339
1341 REAL8TimeSeries **hplus,
1342 REAL8TimeSeries **hcross,
1343 const char *waveform,
1344 REAL8 amplitude,
1345 REAL8 f_high,
1346 REAL8 delta_t
1347)
1348{
1349 COMPLEX16FrequencySeries *tilde_h;
1350 REAL8FFTPlan *plan;
1351 REAL8Window *window;
1353 int length;
1354 int i;
1355 /* low frequency cut-off in Hertz */
1356 const double f_low = 1.0;
1357
1358 /* check input */
1359
1360 if(amplitude < 0 || f_high < f_low || delta_t <= 0) {
1361 XLALPrintError("%s(): invalid input parameters\n", __func__);
1362 *hplus = *hcross = NULL;
1364 }
1365
1366 /* length of the injection time series is 9 / f_low, rounded to
1367 * the nearest odd integer. at that length the waveform's
1368 * amplitude has decayed to the level of numerical noise in the FFT
1369 * so there's no advantage in making it longer. */
1370
1371 length = (int) (9.0 / f_low / delta_t / 2.0);
1372 length = 2 * length + 1;
1373
1374 /* the middle sample is t = 0 */
1375
1376 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t))
1378
1379 /* allocate time and frequency series and FFT plan */
1380
1381 *hplus = XLALCreateREAL8TimeSeries("string cusp +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1382 *hcross = XLALCreateREAL8TimeSeries("string cusp x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
1383 tilde_h = XLALCreateCOMPLEX16FrequencySeries("string cusp +", &epoch, 0.0, 1.0 / (length * delta_t), &lalDimensionlessUnit, length / 2 + 1);
1384 plan = XLALCreateReverseREAL8FFTPlan(length, 0);
1385 if(!*hplus || !*hcross || !tilde_h || !plan) {
1390 *hplus = *hcross = NULL;
1392 }
1393 XLALUnitMultiply(&tilde_h->sampleUnits, &(*hplus)->sampleUnits, &lalSecondUnit);
1394
1395 /* zero the x time series, injection is done in + only */
1396
1397 memset((*hcross)->data->data, 0, (*hcross)->data->length * sizeof(*(*hcross)->data->data));
1398
1399 /* construct the waveform in the frequency domain */
1400
1401 if(strcmp( waveform, "cusp" ) == 0) {
1402 for(i = 0; (unsigned) i < tilde_h->data->length; i++) {
1403 double f = tilde_h->f0 + i * tilde_h->deltaF;
1404
1405 /* frequency-domain wave form. includes taper factor above
1406 * h_high, and phase shift to put waveform's peak on the
1407 * middle sample of the time series */
1408
1409 double amp = amplitude * pow(1. + f_low * f_low / (f * f), -4.) * pow(f, -4. / 3.) * (f > f_high ? exp(1. - f / f_high) : 1.);
1410
1411 tilde_h->data->data[i] = amp * cexp(-I * LAL_PI * i * (length - 1) / length);
1412 }
1413 } else if(strcmp( waveform, "kink" ) == 0) {
1414 for(i = 0; (unsigned) i < tilde_h->data->length; i++) {
1415 double f = tilde_h->f0 + i * tilde_h->deltaF;
1416
1417 /* frequency-domain wave form. includes taper factor above
1418 * h_high, and phase shift to put waveform's peak on the
1419 * middle sample of the time series */
1420
1421 double amp = amplitude * pow(1. + f_low * f_low / (f * f), -4.) * pow(f, -5. / 3.) * (f > f_high ? exp(1. - f / f_high) : 1.);
1422
1423 tilde_h->data->data[i] = amp * cexp(-I * LAL_PI * i * (length - 1) / length);
1424 }
1425 } else if(strcmp( waveform, "kinkkink" ) == 0) {
1426 for(i = 0; (unsigned) i < tilde_h->data->length; i++) {
1427 double f = tilde_h->f0 + i * tilde_h->deltaF;
1428
1429 /* frequency-domain wave form. includes taper factor above
1430 * h_high, and phase shift to put waveform's peak on the
1431 * middle sample of the time series */
1432
1433 double amp = amplitude * pow(1. + f_low * f_low / (f * f), -4.) * pow(f, -2.0);
1434
1435 tilde_h->data->data[i] = amp * cexp(-I * LAL_PI * i * (length - 1) / length);
1436 }
1437 } else {
1438 XLALPrintError("%s(): invalid waveform. must be cusp, kink, or kinkkink\n", __func__);
1439 *hplus = *hcross = NULL;
1441 }
1442
1443 /* set DC and Nyquist to zero */
1444
1445 tilde_h->data->data[0] = tilde_h->data->data[tilde_h->data->length - 1] = 0;
1446
1447 /* transform to time domain */
1448
1449 i = XLALREAL8FreqTimeFFT(*hplus, tilde_h, plan);
1452 if(i) {
1455 *hplus = *hcross = NULL;
1457 }
1458
1459 /* force the sample rate incase round-off has shifted it a bit */
1460
1461 (*hplus)->deltaT = (*hcross)->deltaT = delta_t;
1462
1463 /* apply a Tukey window for continuity at the start and end of the
1464 * injection. the window's shape parameter sets what fraction of
1465 * the window is used by the tapers */
1466
1467 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
1468 if(!window) {
1471 *hplus = *hcross = NULL;
1473 }
1474 for(i = 0; i < (int) window->data->length; i++)
1475 (*hplus)->data->data[i] *= window->data->data[i];
1476 XLALDestroyREAL8Window(window);
1477
1478 /* done */
1479
1480 return XLAL_SUCCESS;
1481}
1482
1483/*
1484 * ============================================================================
1485 *
1486 * String Cusp
1487 *
1488 * ============================================================================
1489 */
1490
1491
1492/**
1493 * @brief Generates cosmic string cusp waveforms.
1494 *
1495 * @details
1496 * Generates the \f$h_{+}\f$ and \f$h_{\times}\f$ components of a cosmic
1497 * string cusp waveform.
1498 *
1499 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1500 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1501 * failure.
1502 *
1503 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1504 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1505 * on failure.
1506 *
1507 * @param[in] amplitude Waveform's amplitude parameter, \f$A\f$, in units
1508 * of \f$\mathrm{strain}\,\mathrm{s}^{-\frac{1}{3}}\f$.
1509 *
1510 * @param[in] f_high High frequency cut-off, \f$f_{\mathrm{high}}\f$, in
1511 * Hertz.
1512 *
1513 * @param[in] delta_t Sample period of output time series in seconds.
1514 *
1515 * @retval 0 Success
1516 * @retval <0 Failure
1517 */
1518
1519
1521 REAL8TimeSeries **hplus,
1522 REAL8TimeSeries **hcross,
1523 REAL8 amplitude,
1524 REAL8 f_high,
1525 REAL8 delta_t
1526)
1527{
1528 /* call waveform generator function */
1529 XLAL_CHECK(XLALGenerateString(hplus, hcross, "cusp", amplitude, f_high, delta_t) == XLAL_SUCCESS, XLAL_EFUNC);
1530
1531 return XLAL_SUCCESS;
1532}
1533
1534/*
1535 * ============================================================================
1536 *
1537 * String Kink
1538 *
1539 * ============================================================================
1540 */
1541
1542
1543/**
1544 * @brief Generates cosmic string kink waveforms.
1545 *
1546 * @details
1547 * Generates the \f$h_{+}\f$ and \f$h_{\times}\f$ components of a cosmic
1548 * string kink waveform.
1549 *
1550 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1551 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1552 * failure.
1553 *
1554 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1555 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1556 * on failure.
1557 *
1558 * @param[in] amplitude Waveform's amplitude parameter, \f$A\f$, in units
1559 * of \f$\mathrm{strain}\,\mathrm{s}^{-\frac{1}{3}}\f$.
1560 *
1561 * @param[in] f_high High frequency cut-off, \f$f_{\mathrm{high}}\f$, in
1562 * Hertz.
1563 *
1564 * @param[in] delta_t Sample period of output time series in seconds.
1565 *
1566 * @retval 0 Success
1567 * @retval <0 Failure
1568 */
1569
1570
1572 REAL8TimeSeries **hplus,
1573 REAL8TimeSeries **hcross,
1574 REAL8 amplitude,
1575 REAL8 f_high,
1576 REAL8 delta_t
1577)
1578{
1579 /* call waveform generator function */
1580 XLAL_CHECK(XLALGenerateString(hplus, hcross, "kink", amplitude, f_high, delta_t) == XLAL_SUCCESS, XLAL_EFUNC);
1581
1582 return XLAL_SUCCESS;
1583}
1584
1585/*
1586 * ============================================================================
1587 *
1588 * String KinkKink
1589 *
1590 * ============================================================================
1591 */
1592
1593
1594/**
1595 * @brief Generates cosmic string kink waveforms.
1596 *
1597 * @details
1598 * Generates the \f$h_{+}\f$ and \f$h_{\times}\f$ components of a cosmic
1599 * string kink waveform.
1600 *
1601 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the
1602 * address of the newly allocated \f$h_{+}\f$ time series. Set to NULL on
1603 * failure.
1604 *
1605 * @param[out] hcross Address of a REAL8TimeSeries pointer to be set to the
1606 * address of the newly allocated \f$h_{\times}\f$ time series. Set to NULL
1607 * on failure.
1608 *
1609 * @param[in] amplitude Waveform's amplitude parameter, \f$A\f$, in units
1610 * of \f$\mathrm{strain}\,\mathrm{s}^{-\frac{1}{3}}\f$.
1611 *
1612 * @param[in] delta_t Sample period of output time series in seconds.
1613 *
1614 * @retval 0 Success
1615 * @retval <0 Failure
1616 */
1617
1618
1620 REAL8TimeSeries **hplus,
1621 REAL8TimeSeries **hcross,
1622 REAL8 amplitude,
1623 REAL8 delta_t
1624)
1625{
1626 /* call waveform generator function. the f_high parameter is set as
1627 * NaN, which will be ignored when calculating the spectrum */
1628 XLAL_CHECK(XLALGenerateString(hplus, hcross, "kinkkink", amplitude, XLAL_REAL8_FAIL_NAN, delta_t) == XLAL_SUCCESS, XLAL_EFUNC);
1629
1630 return XLAL_SUCCESS;
1631}
1632
1633
1634/*
1635 * ============================================================================
1636 *
1637 * Cherenkov Radiation
1638 *
1639 * ============================================================================
1640 */
1641
1642
1643/**
1644 * @brief Generates Cherenkov like waveforms.
1645 *
1646 * @details
1647 * Generates the \f$h_{+}\f$ and \f$h_{\times}\f$ components of a Cherenkov
1648 * like waveforms. Since cherenkov radiation is linealy polirized, \f$h_{\times}\f$ component is set
1649 * to be zero.
1650 *
1651 * the power spectrum of chrenkov radiation is given by the Frank-Tamm formula as follows
1652 *
1653 * \f{equation}{
1654 * \frac{\diff W}{\diff x\diff \omega}
1655 * = \frac{e^2}{c^2}\left(1-\frac{1}{\beta^2n^2(\omega)}\right)\omega,n\beta>1
1656 * \f}
1657 *
1658 * \f$n\beta\f$ represents the ratio of velocity of the source and wave speed of the medium.
1659 * On the purpose to mimic the situation into gravitational Cherenkov radiation, we choose \f$n\beta\f$
1660 * as a speed of velocity in light speed units. The refractive index of the medium is actually a
1661 * function of frequency, however, it should be considered as a fixed value for the situation where
1662 * the source moving in vacuum. In the end, free parameter we can choose is length of the source
1663 * which limits the cut off frequency although the nyquist frequency is sufficiently lower than the
1664 * calculated cut off frequency assuming the length of the source to be about 100 meters order.
1665 *
1666 * @param[out] hplus Address of a REAL8TimeSeries pointer to be set to the address of the newly allocated
1667 *\f$h_{+}\f$ time series. Set to NULL on failure.
1668 *
1669 * @param[out] hcross Adress of a REAL8TimeSeries pointer to be set to the address of the newly allocated
1670 * \f$h_{\times}\f$ time series. Set to NULL on failure.
1671 *
1672 * @param[in] source_length The length of the source in meters.
1673 *
1674 * @param[in] dE_over_dA The waveform which is created with this arbitrary amplitude.in Joules per square metre.
1675 *
1676 * @param[in] deltaT Sample period of output time series in seconds.
1677 *
1678 * @retval 0 Success
1679 * @retval <0 Failure
1680 */
1681
1682
1684 REAL8TimeSeries **hplus,
1685 REAL8TimeSeries **hcross,
1686 double source_length,
1687 double dE_over_dA,
1688 double deltaT
1689 )
1690{
1692 REAL8FFTPlan *plan;
1693 REAL8Window *window;
1694 COMPLEX16FrequencySeries *tilde_h;
1695 int length;
1696 unsigned int i;
1697 const double f_low = 10; /* low cut frequency in Heltz */
1698 double f_high;
1699 double norm_factor;
1700
1701 /* length of the injection is nearest interger of 8/f_low. This
1702 * length is choosen because even if you set f_high as almost same
1703 * as f_low, amplitude decayed to small enough value at this
1704 * length.*/
1705 length = (int) floor(8.0 / f_low / deltaT / 2.0);
1706 length = length * 2 + 1;
1707
1708 /* middle of the sample is t=0 */
1709 if(!XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * deltaT))
1711
1712 /* compute the high frequency cut off */
1713 f_high = LAL_C_SI / source_length;
1714
1715 /* check the input */
1716 if(f_high < f_low || source_length <= 0. || deltaT <= 0. || dE_over_dA <= 0.){
1717 *hplus = *hcross = NULL;
1719 }
1720
1721 /* allocate memories. */
1722 *hplus = XLALCreateREAL8TimeSeries("cherenkov +", &epoch, 0.0, deltaT, &lalStrainUnit, length);
1723 *hcross = XLALCreateREAL8TimeSeries("cherenkov x", &epoch, 0.0, deltaT, &lalStrainUnit, length);
1724 tilde_h = XLALCreateCOMPLEX16FrequencySeries("cherenkov +", &epoch, 0.0, 1.0 / (length * deltaT), &lalDimensionlessUnit, length / 2 + 1);
1725 XLALUnitMultiply(&tilde_h->sampleUnits, &(*hplus)->sampleUnits, &lalSecondUnit);
1726
1727 /* set hcross to be 0 because it is linearly polarized. */
1728
1729 memset((*hcross)->data->data, 0, (*hcross)->data->length * sizeof(*(*hcross)->data->data));
1730
1731 /* calculate the wave form in frequency domain from the given
1732 * spectrum. Assuming, the energy spectrum gravitaional waves in
1733 * frequency domain is proportional to /f$f^2|\tilde_h(f)|^2/f$ */
1734 norm_factor = sqrt(dE_over_dA * 4. * LAL_G_SI / (LAL_PI * LAL_C_SI * LAL_C_SI * LAL_C_SI * f_high * f_high));
1735 /* correction of the removal of half of the waveform by causality window. */
1736 norm_factor *= sqrt(2.);
1737 for(i = 0; i < tilde_h->data->length; i++) {
1738 double f = tilde_h->f0 + tilde_h->deltaF * i;
1739 if(f_low <= f && f <= f_high)
1740 tilde_h->data->data[i] = norm_factor * cexp(I * LAL_PI * i * (length - 1) / length) / sqrt(f);
1741 else
1742 tilde_h->data->data[i] = 0.;
1743 }
1744
1745 tilde_h->data->data[0] = tilde_h->data->data[tilde_h->data->length - 1] = 0;
1746
1747 /* perform ReverseFFT to create time domain series. */
1748 plan = XLALCreateReverseREAL8FFTPlan((*hplus)->data->length, 0);
1749 if(XLALREAL8FreqTimeFFT(*hplus,tilde_h,plan)) {
1754 *hplus = *hcross = NULL;
1756 }
1759 /* restore this to fix round-off issues */
1760 (*hplus)->deltaT = deltaT;
1761
1762 /* apply Tukey window. */
1763 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
1764 if(!window) {
1767 *hplus = *hcross = NULL;
1769 }
1770
1771 /* apply gaussian window in \f$t<0\f$ to make the waveform looks
1772 * time causal FIXME: multiplying window in time domain causes
1773 * convolution in frequecny domain It will changes the feature of
1774 * spectrum from the one we want to get */
1775 for(i = 0; i < (window->data->length - 1) / 2; i++) {
1776 double duration = 3. / f_high;
1777 double t = (i - (window->data->length - 1) / 2) * deltaT;
1778 window->data->data[i] *= exp(-0.5 * t * t / (duration * duration));
1779 }
1780
1781 /* multiply waveform by window */
1782 for(i = 0; i < (*hplus)->data->length; i++)
1783 (*hplus)->data->data[i] *= window->data->data[i];
1784
1785 XLALDestroyREAL8Window(window);
1786
1787 /* done the program. */
1788 return XLAL_SUCCESS;
1789}
1790
1791
1792/*
1793 * ============================================================================
1794 *
1795 * Cherenkov energy calculation
1796 *
1797 * ============================================================================
1798 */
1799
1800
1801/**
1802 * @brief energy calculating function for Cherenkov burst.
1803 *
1804 * @details
1805 * Calculate the energy intensity for the Cherenkov burst considering that Cherenkov radiation would
1806 * make cone shaped wavefront.
1807 *
1808 * @param[in] power power of the source in watts
1809 *
1810 * @param[in] beta the velocity of the source in units of light speed
1811 *
1812 * @param[in] r impact parameter. perpendicular distance between antenna and particle path in metres
1813 *
1814 * @retval 0 Success
1815 * @retval <0 Failure
1816 */
1817
1818
1820 double power,
1821 double beta,
1822 double r
1823 )
1824{
1825 /* dE / dx = P dt / (c * beta * dt)
1826 * dA / dx = 2 * pi * r * c * beta * sin(theta) * dt / (c * beta * dt)
1827 * the Cherenkov angle is decided by beta. cos(theta) = 1 / beta. */
1828 return power / (LAL_TWOPI * r * LAL_C_SI * beta * sqrt(1. - 1. / beta / beta));
1829}
static int XLALGenerateString(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const char *waveform, REAL8 amplitude, REAL8 f_high, REAL8 delta_t)
Function for generating cosmic string waveforms.
Definition: LALSimBurst.c:1340
static void semi_major_minor_from_e(double e, double *a, double *b)
Definition: LALSimBurst.c:77
static void gaussian_noise(REAL8TimeSeries *series, double rms, gsl_rng *rng)
Definition: LALSimBurst.c:61
static double beta(const double a, const double b, const sysq *system)
Internal function that computes the spin-orbit couplings.
static REAL8 sum(REAL8 *arr1, REAL8 *arr2, int k)
double i
Definition: bh_ringdown.c:118
double e
Definition: bh_ringdown.c:117
#define LAL_CHECK_CONSISTENT_TIME_SERIES(s1, s2, val)
double duration
const double Q
const double w
sigmaKerr data[0]
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_C_SI
#define LAL_PI
#define LAL_TWOPI
#define LAL_G_SI
double complex COMPLEX16
double REAL8
int XLALSimBurstSineGaussian(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 Q, REAL8 centre_frequency, REAL8 hrss, REAL8 eccentricity, REAL8 phase, REAL8 delta_t)
Generate sine- and cosine-Gaussian waveforms with various polarizations and phases.
Definition: LALSimBurst.c:1080
double XLALSimBurstCherenkov_dE_dA(double power, double beta, double r)
energy calculating function for Cherenkov burst.
Definition: LALSimBurst.c:1819
REAL8 XLALMeasureIntHDotSquaredDT(const COMPLEX16FrequencySeries *fseries)
Computes the integral of the square of a real-valued time series' first derivative from its Fourier t...
Definition: LALSimBurst.c:250
int XLALGenerateStringKinkKink(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 amplitude, REAL8 delta_t)
Generates cosmic string kink waveforms.
Definition: LALSimBurst.c:1619
double XLALSimBurstSineGaussianQ(double duration, double centre_frequency)
Compute the Q of a sine-Gaussian waveform from the duration and centre frequency.
Definition: LALSimBurst.c:975
REAL8 XLALMeasureHrss(const REAL8TimeSeries *hplus, const REAL8TimeSeries *hcross)
Computes "root-sum-square strain", or .
Definition: LALSimBurst.c:218
int XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 duration, REAL8 frequency, REAL8 bandwidth, REAL8 eccentricity, REAL8 phase, REAL8 int_hdot_squared, REAL8 delta_t, gsl_rng *rng)
Generate a band- and time-limited white-noise burst waveform with Gaussian envelopes in the time and ...
Definition: LALSimBurst.c:745
double XLALSimBurstSineGaussianDuration(double Q, double centre_frequency)
Compute the duration of a sine-Gaussian waveform from the Q and centre frequency.
Definition: LALSimBurst.c:1007
int XLALSimBurstGaussian(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 duration, REAL8 hrss, REAL8 delta_t)
Generate Gaussian waveforms.
Definition: LALSimBurst.c:1215
REAL8 XLALMeasureEoverRsquared(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
Computes the areal energy density carried by a gravitational wave.
Definition: LALSimBurst.c:340
int XLALGenerateImpulseBurst(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 hpeak, REAL8 delta_t)
Genereates a single-sample impulse waveform.
Definition: LALSimBurst.c:419
int XLALGenerateStringKink(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 amplitude, REAL8 f_high, REAL8 delta_t)
Generates cosmic string kink waveforms.
Definition: LALSimBurst.c:1571
COMPLEX16 XLALMeasureHPeak(const REAL8TimeSeries *hplus, const REAL8TimeSeries *hcross, unsigned *index)
Return the strain of the sample with the largest magnitude.
Definition: LALSimBurst.c:113
REAL8 XLALMeasureIntS1S2DT(const REAL8TimeSeries *s1, const REAL8TimeSeries *s2)
Computes the integral of the product of two time series.
Definition: LALSimBurst.c:164
int XLALGenerateStringCusp(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 amplitude, REAL8 f_high, REAL8 delta_t)
Generates cosmic string cusp waveforms.
Definition: LALSimBurst.c:1520
int XLALSimBurstCherenkovRadiation(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, double source_length, double dE_over_dA, double deltaT)
Generates Cherenkov like waveforms.
Definition: LALSimBurst.c:1683
static const INT4 r
static const INT4 a
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
const LALUnit lalDimensionlessUnit
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
REAL8Window * XLALCreateGaussREAL8Window(UINT4 length, REAL8 beta)
REAL8Window * XLALCreateTukeyREAL8Window(UINT4 length, REAL8 beta)
void XLALDestroyREAL8Window(REAL8Window *window)
#define XLAL_ERROR_REAL8(...)
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_REAL8_FAIL_NAN
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_EBADLEN
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EDOM
XLAL_EINVAL
XLAL_EFPDIV0
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
x
COMPLEX16Sequence * data
COMPLEX16 * data
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
REAL8Sequence * data
LIGOTimeGPS epoch
Definition: unicorn.c:20
double hrss
Definition: unicorn.c:21
double deltaT
Definition: unicorn.c:24