LALSimulation  5.4.0.1-fe68b98
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 
61 static 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 
77 static 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 
113 COMPLEX16 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  *
482 The construction of a BTLWNB waveform with duration \f$\Delta t\f$ and
483 bandwidth \f$\Delta f\f$ centred on \f$f_{0}\f$ begins by populating a time
484 series with independent Gaussian random numbers. The origin of the time
485 co-ordinate corresponds to the middle sample in the time series. We apply
486 an initial time-limiting window function to the time series by multiplying
487 the time series with a Gaussian window function
488 \f{equation}{
489 w_{1}(t)
490  \propto \ee^{-\frac{1}{2} t^{2} / \sigma_{t}^{2}},
491 \f}
492 where \f$\sigma_{t}\f$ sets the duration of the window. The windowed time
493 series is then Fourier transformed and a second Gaussian window applied in
494 the 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}
499 where \f$\sigma_{f} = \frac{1}{2} \Delta f\f$.
500 
501 Since the inital time series is real-valued, the negative frequency
502 components of the Fourier transform are the complex conjugates of the
503 positive frequency components and need not be stored. The frequency-domain
504 filter is real-valued (phase preserving), and so when the positive
505 frequency components are the only ones being stored applying the window
506 function to them alone achieves the correct result.
507 
508 The multiplication of the frequency domain data by the window function is
509 equivalent to convolving the time domain data with the Fourier transform of
510 the 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
512 effect of spreading the signal in the time domain, i.e.\ increasing its
513 duration. 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
515 application of the frequency domain window. The inverse Fourier transform
516 of \f$\tilde{w}_{2}(f)\f$ is
517 \f{equation}{
518 w_{2}(t)
519  \propto \ee^{-2 \pi^{2} \sigma_{f}^{2} t^{2}}.
520 \f}
521 The result of convolving two Gaussians with one another is another
522 Gaussian, so the effective time-domain window is
523 \f{equation}{
524 w(t)
525  = w_{1}(t) \otimes w_{2}(t)
526  \propto \ee^{-\frac{1}{2} t^{2} / \sigma^{2}},
527 \f}
528 where
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}
534 We wish this Gaussian's width to be \f$\sigma = \frac{1}{2} \Delta t\f$,
535 therefore
536 \f{equation}{
537 \sigma_{t}
538  = \sqrt{\frac{1}{4} \Delta t^{2} - \frac{1}{\pi^{2} \Delta f^{2}}}.
539 \f}
540 Note 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 
546 After application of the frequency domain window the data is inverse
547 transformed to the time domain for injection into the strain data.
548 
549 ### Details
550 
551 This function produces both \f$h_{+}\f$ and \f$h_{\times}\f$ waveforms.
552 These are independent waveforms constructed by applying the time series
553 construction algorithm twice. The length of the result is \f$21 \Delta
554 t\f$ rounded to the nearest odd integer,
555 \f{equation}{
556 L
557  = 2 \left\lfloor \frac{1}{2} \frac{21 \Delta t}{\delta t} \right\rfloor
558  + 1
559 \f}
560 where \f$\delta t\f$ is the sample period of the time series. The middle
561 sample is \f$t = 0\f$, so the first and last samples are at \f$t = \pm \delta
562 t (L - 1) / 2\f$. The time-domain Gaussian window is constructed with a
563 call 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}
568 The numerator transforms the normalized co-ordinate \f$y \in [-1, +1]\f$ in
569 the definition of the window function to \f$t\f$. (See the LAL
570 documentation for more information. Sample index 0 is \f$y = -1\f$, sample
571 index \f$L - 1\f$ is \f$y = +1\f$, so there are \f$(L - 1) / 2\f$ sample indexes
572 per unit of \f$y\f$.)
573 
574 The time series is transformed to the frequency domain with a call to
575 <tt>XLALREAL8TimeFreqFFT()</tt>, which populates the metadata of the output
576 frequency series with the appropriate values. There are \f$(L + 1) / 2\f$
577 complex-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
579 a call to <tt>XLALCreateGaussREAL8Window()</tt> requesting a window with a
580 length of \f$L + 2\f$ (twice the length of the frequency series rounded up to
581 the next odd integer), and a shape parameter of
582 \f{equation}{
583 \beta
584  = \frac{(L + 1) \delta f / 2}{\sigma_{f}}.
585 \f}
586 The 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
588 frequency. (See the LAL documentation for more information. The
589 window 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
591 unit of \f$y\f$.) The window is created with the peak in the middle sample
592 at index \f$(L + 1) / 2\f$, and we use <tt>XLALResizeREAL8Sequence()</tt> to
593 extract as many samples as there are in the frequency series with the peak
594 shifted 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 
598 Following application of the frequency-domain window, the injection is
599 transformed back to the time domain with a call to
600 <tt>XLALREAL8FreqTimeFFT()</tt>. If \f$\tilde{h}_{k}\f$ are the complex
601 values in the frequency bins, the output time series is
602 \f{equation}{
603 h_{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}
608 where \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}
614 and 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}
628 This relationship is used to normalize the injection time series. The
629 expression on the left hand side is \f$\int \dot{h}^{2} \diff t\f$. For both
630 polarizations the right hand side is computed in the frequency domain
631 following application of the Gaussian window, and the amplitudes of the
632 frequency 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
634 value.
635 
636 To ensure no discontinuities in the strain time series when the injection
637 is added to it, a final Tukey window is applied to the injection in the
638 time domain. The Tukey window is constructed with a call to
639 <tt>XLALCreateTukeyREAL8Window()</tt> with a shape parameter of \f$\beta =
640 0.5\f$ so that the tapers span a total of 50\% of the time series.
641 Because the Tukey window is flat with unit amplitude in the middle, it has
642 no effect on the injection time series where the bulk of the energy is
643 concentrated, and the large tapers ensure the Tukey window induces
644 negligble spread of the injection in the frequency domain. Because the
645 injection is normalized in the frequency domain prior to transformation to
646 the time domain, the application of the Tukey window does bias the
647 normalization slightly by reducing the total energy in the injection,
648 however the Tukey window's tapers start several \f$\sigma_{t}\f$ away from
649 the injection's peak and so this effect is negligble.
650 
651 In order that the waveforms be reproducable so that an analysis can be
652 repeated, or the waveforms constructed multiple times for injection into
653 the strain data from more than one instrument, it is necessary to specify
654 how the initial time series of independent Gaussian random numbers is to be
655 constructed. This is done by specifying the seed to be used with the
656 random number generator. The random number generator is not specified, so
657 the same seed may produce different injections with different versions of
658 the code, but a seed and revision tag combination should be guaranteed to
659 produce the same injection. Note also that changing the length of the
660 injection time series changes the number of random numbers used to
661 construct it, so the injection waveform also depends on the time series'
662 sample rate. One has to be careful when constructing injection waveforms
663 for instruments with different sample rates (e.g., LIGO and VIRGO). The
664 injection must be constructed at the same sample rate for both instruments
665 and then up- or down-sampled as needed when injected into each instrument's
666 time series.
667 
668 \anchor xlalsimburstbtlwnb_examples
669 \image html lalsimburst_btlwnbexamples.svg
670 Example of the \f$+\f$ and \f$\times\f$ polarizations of a band- and
671 time-limited white-noise burst injection waveforms with different degrees
672 of 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,
748  REAL8 duration,
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  }
826  XLALDestroyREAL8Window(window);
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  }
937  XLALDestroyREAL8Window(window);
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) {
1145  XLALDestroyREAL8TimeSeries(*hcross);
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,
1218  REAL8 duration,
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) {
1255  XLALDestroyREAL8TimeSeries(*hcross);
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) {
1387  XLALDestroyREAL8TimeSeries(*hcross);
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) {
1454  XLALDestroyREAL8TimeSeries(*hcross);
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) {
1470  XLALDestroyREAL8TimeSeries(*hcross);
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)) {
1751  XLALDestroyREAL8TimeSeries(*hcross);
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) {
1766  XLALDestroyREAL8TimeSeries(*hcross);
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)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
const LALUnit lalDimensionlessUnit
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
void XLALDestroyREAL8Window(REAL8Window *window)
REAL8Window * XLALCreateGaussREAL8Window(UINT4 length, REAL8 beta)
REAL8Window * XLALCreateTukeyREAL8Window(UINT4 length, REAL8 beta)
#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)
list 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